<分区>
我偶然发现了一个奇怪的错误/问题。
我有一个 MySQL 表,其中有一列用数字 (BIGINT) 填充。这些数字对于常规的 32 位整数来说太大了,因此 PHP 会将它们转换为 32 位的字符串。这每次都会给出正确的结果。
当在 64 位 PHP 上运行并且不使用 $variable = (string)$variable
强制转换为字符串时,结果有时会减 1,例如像 1293203059233 这样的数字变成了 1293203059232。这显然不好。奇怪的是我看不到任何模式。
MySQL 中的一行有时递减有时不递减并不是随机发生的,而是相同的整数/行总是递减,并且总是递减 1。
什么会导致这种情况?我使用 json_encode
将 stdClass
对象或 arrays()
转换为文本,然后通过常规 HTTP 响应发送它们。
mysqli
使用准备好的语句检索行,例如:
$stmt = $sql->prepare->("SELECT BIGNUMBER FROM table WHERE SOMEID = ?");
$stmt->bind_result($bignumber);
$stmt->bind_param("i",$someid);
$stmt->execute();
$stmt->fetch();
$stmt->close();
$obj = new stdClass();
$obj->number = $bignumber;
echo json_encode($obj);
我在浏览数据库表时验证了所有的整数都是正确的。
一些示例(这些是实际值):
不转换为字符串:
10205160559939609 -> 10205160669939608 // bad
与:
10205160559939609 -> "10205160559939609" // good
不转换为字符串:
10154493437278508 -> 10154493437278508 // good (?)
与:
10154493437278508 -> "10154493437278508" // good
编辑:我在 json_encode 之前做了一个 error_log 测试来测试,产生:
as Strng: (used error_log((string)$number);)
10205160559939609
as int: (used error_log($number);)
10205160559939609
这表明 php 确实获得了正确的值,并且错误发生在 php json_encode 或浏览器的解码方法中。