PHP randomly reduces large integers by 1

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 // bad 

with:

 10205160559939609 -> "10205160559939609" // good 

without casting to a string:

 10154493437278508 -> 10154493437278508 // good (?) 

with:

 10154493437278508 -> "10154493437278508" // good 

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.

+6
source share
1 answer

Just enter 10205150669939609 in the chrome console so that you get a printed number (round effect) 10205150669939608. I think integers, large, are not valid in JS, so they should not be in JSON either. I would use strings if I had large values.

+2
source

All Articles