I came across a strange error / problem.
I have a MySQL table with a column filled with numbers (BIGINT). These numbers are too large for a regular 32-bit integer, so PHP will pass them to a string on a 32-bit one. This gives the correct result every time.
When running in 64-bit PHP and without forced translation into a string with $variable = (string)$variable result will sometimes decrease by 1, so a number like 1293203059233 becomes 1293203059232. This is not very obvious. The strange thing is that I do not see any picture.
This happens randomly, so one row from MySQL sometimes decreases, and sometimes not, but such that the same integers / rows always decrease and always by 1.
What could be the reason for this? I use json_encode to convert stdClass objects or arrays() to text, then send them using regular HTTP responses.
Strings are retrieved by mysqli using prepared statements, such as:
$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);
I have verified that all integers are correct when viewing the database table.
Some examples (these are actual values):
without casting to a string:
10205160559939609 -> 10205160669939608
with:
10205160559939609 -> "10205160559939609"
without casting to a string:
10154493437278508 -> 10154493437278508
with:
10154493437278508 -> "10154493437278508"
Edit: I checked the error_log test pre-json_encode for testing, yielding:
as Strng: (used error_log((string)$number);) 10205160559939609 as int: (used error_log($number);) 10205160559939609
This indicates that php is getting the correct value and that the error occurs either in php json_encode or in the browser decoding method.