我偶然发现了一个奇怪的错误/问题.
我有一个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);
Run Code Online (Sandbox Code Playgroud)
我已经验证浏览数据库表时所有整数都是正确的.
一些例子(这些是实际值):
没有转换为字符串:
10205160559939609 -> 10205160669939608 // bad
Run Code Online (Sandbox Code Playgroud)
有:
10205160559939609 -> "10205160559939609" // good
Run Code Online (Sandbox Code Playgroud)
没有转换为字符串:
10154493437278508 -> 10154493437278508 // good (?)
Run Code Online (Sandbox Code Playgroud)
有:
10154493437278508 -> "10154493437278508" // good
Run Code Online (Sandbox Code Playgroud)
编辑:我做了一个error_log测试pre-json_encode来测试,产生:
as Strng: (used error_log((string)$number);)
10205160559939609
as int: (used error_log($number);) …Run Code Online (Sandbox Code Playgroud) 据我了解,JSON_BIGINT_AS_STRING仅为5.4+.我需要在5.1+环境中重现相同的行为.代码是分布式的,我无法控制它将运行的环境.我有什么选择(除了编写自己的json解析器)?有没有经过验证的成熟解决方案?