|
|
|
ความฉิบหายจาก PHP 8.1 & PDO |
|
|
|
|
|
|
|
ใครใช้งาน PDO Mysql มาก่อน PHP 8.1 อาจจะ 5.x, 7.x, 8.0 ก็ตาม ให้ตรวจตราดูด้วยนะครับ เพราะมันคือความพินาศระดับไม่ธรรมดาทีเดียว! ต้องใช้คำว่าฉิบหายกันเลย
มีตัวอย่างข้อมูลอยู่ประมาณนี้
Code (SQL)
CREATE TABLE IF NOT EXISTS `dummy_people` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`test_double` double(20,9) NOT NULL,
`add` date DEFAULT NULL,
`update` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=122 ;
--
-- Dumping data for table `dummy_people`
--
INSERT INTO `dummy_people` (`id`, `name`, `address`, `test_double`, `add`, `update`) VALUES
(1, 'Madyson Cummerata', '332 Jast Knoll\nEast Carolanne, WA 70869-1568', 12.458100000, '1981-03-06', '2020-12-30'),
(2, 'Mrs. Kathlyn Olson', '', 0.000000000, '2000-12-16', '2005-09-06'),
(3, 'Freeda Hodkiewicz', '23132 Kovacek Alley Apt. 060\nHowellfort, NJ 47945', 0.000000000, '1996-02-12', '2006-01-07'),
(4, 'Shanny Weissnat', '63976 Huels Inlet\nSouth Noemiehaven, CA 60696-8648', 0.000000000, '2009-10-01', '2017-06-10'),
(5, 'Demarcus Huels', '627 Reynolds Plain\nNorth Nicoport, MD 72711-7777', 0.000000000, '1977-11-04', '1998-10-18'),
(6, 'Vivianne Ankunding', '', 0.000000000, '1992-07-01', '2009-10-09'),
(7, 'Mrs. Tiffany Zboncak III', '16701 Kariane Trafficway\nWest Marvinborough, AR 31211-7884', 0.000000000, '1970-02-18', '1992-12-11'),
(8, 'Prof. Aditya Marks DVM', '', 0.000000000, '1973-08-20', '1979-07-09'),
(9, 'Demarcus Reichel', '336 Ulises Gateway\nLehnerfurt, MS 11457', 0.000000000, '1976-06-10', '2002-07-22'),
(10, 'Dr. Clifford Pfannerstill III', '2171 Swift Street\nNew Elenora, NE 09377-3135', 0.000000000, '1974-04-07', '1995-08-17');
แล้วก็โค้ดประมาณนี้
Code (PHP)
$db = 'test_generic-tests';
$dsn = 'mysql:host=localhost;dbname=' . $db . ';charset=utf8';
$user = 'user';
$pass = 'pass';
$options = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_OBJ,
];
$sql = 'SELECT * FROM `dummy_people` LIMIT 0, 1';
$PDO = new \PDO($dsn, $user, $pass, $options);
$result = $PDO->query($sql);
var_dump($result->fetchAll());
$result->closeCursor();
unset($PDO, $result);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', $user, $pass, $db);
$mysqli->set_charset('utf8mb4');
$result = $mysqli->query($sql);
var_dump($result->fetch_all());
$result->free_result();
$mysqli->close();
unset($mysqli, $result);
จากโค้ดข้างบน ถ้ารันใน PHP 8.0 หรือเก่ากว่า จะได้ผลลัพธ์คือ
Quote:array (size=1)
0 =>
object(stdClass)[3]
public 'id' => string '1' (length=1)
public 'name' => string 'Madyson Cummerata' (length=17)
public 'address' => string '332 Jast Knoll
East Carolanne, WA 70869-1568' (length=44)
public 'test_double' => string '12.458100000' (length=12)
public 'add' => string '1981-03-06' (length=10)
public 'update' => string '2020-12-30' (length=10)
array (size=1)
0 =>
array (size=6)
0 => string '1' (length=1)
1 => string 'Madyson Cummerata' (length=17)
2 => string '332 Jast Knoll
East Carolanne, WA 70869-1568' (length=44)
3 => string '12.458100000' (length=12)
4 => string '1981-03-06' (length=10)
5 => string '2020-12-30' (length=10)
ข้อสังเกตุคือคอลัมน์ที่เป็น int, double จะส่งกลับมาเป็น string เสมอ ไม่ว่าจะใช้ PDO, MySQLi
ทีนี้ของใหม่ใน PHP 8.1. โค้ดเดียวกันจะได้ผลลัพธ์เป็น
Quote:array (size=1)
0 =>
object(stdClass)[3]
public 'id' => int 1
public 'name' => string 'Madyson Cummerata' (length=17)
public 'address' => string '332 Jast Knoll
East Carolanne, WA 70869-1568' (length=44)
public 'test_double' => float 12.4581
public 'add' => string '1981-03-06' (length=10)
public 'update' => string '2020-12-30' (length=10)
array (size=1)
0 =>
array (size=6)
0 => string '1' (length=1)
1 => string 'Madyson Cummerata' (length=17)
2 => string '332 Jast Knoll
East Carolanne, WA 70869-1568' (length=44)
3 => string '12.458100000' (length=12)
4 => string '1981-03-06' (length=10)
5 => string '2020-12-30' (length=10)
จะเห็นว่ามันส่ง column ที่เป็น int กลับมาเป็น int และ column ที่เป็น double กลับมาเป็น float
ทั้งที่รุ่นก่อนจะเป็น string ทั้งหมด
หมายความว่าการตรวจสอบด้วยเงื่อนไข === จะพัง
การทำงานที่มีการตรวจประเภทตัวแปรก็จะพัง
หรือบางคนที่เก็บค่า int แบบมีศูนย์นำหน้าก็จะพัง ( https://externals.io/message/113294 )
แล้วก็ไม่แน่ใจว่าคนที่เก็บค่าตัวเลขมากๆในคอลัมน์ประเภท int แล้วเอามาคำณวน โดยตัวเลขนั้นจำนวนมากกว่า bit ที่ PHP รองรับมันจะพังไหม? แต่คิดว่าพัง ( ต.ย. https://www.thaicreate.com/php/forum/136505.html )
พวกโปรแกรมการเงินหรือที่ต้องคำณวนแม่นๆนี่คงฉิบหายย่อยยับเป็นแน่.
ตรวจสอบกันดูดีๆนะครับท่านผู้ชม
ปล. ในภาษาอื่นๆอย่างเช่น C#, Python อะไรงี้ มีปัญหาขยันทำพังแบบนี้บ้างมั้ย?
Tag : PHP, MySQL, MySQL
|
|
|
|
|
|
Date :
2022-02-19 21:50:57 |
By :
mr.v |
View :
1558 |
Reply :
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c#
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history
Python
https://docs.python.org/3/whatsnew/3.10.html
ทุกภาษาย่อมมีการเปลี่ยนแปลง
PHP ticket มีสำหรับรายงาน bug เสนอความเห็น หรือ request features ลองดูครับ
(เคยคิดจะส่งไปเหมือนกัน แต่ต้องชี้แจงรายละเอียดหลายส่วน...เลยยอมยกธง 555)
|
|
|
|
|
Date :
2022-02-20 11:15:15 |
By :
009 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 00
|