PHP随机将大整数递减1

nic*_*dnk 6 php mysql json

我偶然发现了一个奇怪的错误/问题.

我有一个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);)
10205160559939609
Run Code Online (Sandbox Code Playgroud)

这表明php确实获得了正确的值,并且错误发生在php json_encode或浏览器的decode方法中.

and*_*rrs 2

只需在 chrome 控制台中输入 10205150669939609 即可打印出数字 10205150669939608(四舍五入效果)。我猜这么大的整数在 JS 中无效,所以它们也不应该在 JSON 中。如果我有这么大的值,我会使用字符串。