Bug #66707 [Com]: big int conversion on json_encode/json_decode

From: Date: Fri, 28 Aug 2015 03:47:16 +0000
Subject: Bug #66707 [Com]: big int conversion on json_encode/json_decode
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-195580@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66707&edit=1 ID: 66707 Comment by: dev at skynar dot co Reported by: sergey dot shilko at gmail dot com Summary: big int conversion on json_encode/json_decode Status: Not a bug Type: Bug Package: JSON related Operating System: Linux PHP Version: 5.5.7 Block user comment: N Private report: N New Comment: A JSON numeric size is not limited by the specification and should not to be related to PHP_INT_MAX, just put numeric strings into json without quotes, if JSON_NUMERIC_CHECK flag exists. i'm sending data to another server, and it needs numeric parameters to be numeric. Am i the only developer in the world who care about variable types? function bigint_json_fix(&$array, $depth=512){ foreach($array as $key=>$value){ if(is_string($value) && is_numeric($value) && $value <= PHP_INT_MAX){ if((int)$value == $value){ $array[$key]=(int)$value; }elseif((float)$value == $value){ $array[$key]=(float)$value; } }elseif(is_array($value) && $depth > 0){ bigint_json_fix($value, $depth-1); $array[$key]=$value; } } } function bigint_json_encode($array, $options=0, $depth=512){ if(($options & JSON_NUMERIC_CHECK) == 0) return json_encode($array, $options, $depth); bigint_json_fix($array, $depth); $json = json_encode($array, $options - JSON_NUMERIC_CHECK, $depth); return preg_replace('!\:\"([0-9]*)\"([\}\,])!', ':$1$2', $json); } echo bigint_json_encode(['myint'=>'43274923749237498273443579'], JSON_NUMERIC_CHECK); // {"myint":43274923749237498273443579} okay now i wonna get numeric string out of json: $data = json_decode('{"myint":43274923749237498273443579}', true, 512, JSON_BIGINT_AS_STRING)); //PHP Notice: json_decode(): integer overflow detected echo $data['myint']; // 9223372036854775807 as i expected, result is corrupted. function bigint_json_decode($json, $assoc=false, $depth=512, $useless_option=0){ if(($useless_option & JSON_BIGINT_AS_STRING) != 0){ $json = preg_replace('!\:([0-9]*)([\}\,])!', ':"$1"$2', $json); } $data = json_decode($json, $assoc, $depth, $useless_option); bigint_json_fix($data); return $data; } $data = bigint_json_decode('{"myint":43274923749237498273443579}'); echo $data['myint']; //43274923749237498273443579 why not to do the same without regular expressions? Previous Comments: ------------------------------------------------------------------------ [2014-02-13 11:38:00] sergey dot shilko at gmail dot com okay then, so its expected. Already using strict datatypes to threat large numbers as strings. Thanks. ------------------------------------------------------------------------ [2014-02-13 11:35:06] sergey dot shilko at gmail dot com echo json_last_error(); //0 echo json_last_error_msg(); //No error ------------------------------------------------------------------------ [2014-02-13 11:33:59] derick@php.net Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://www.php.net/manual/ and the instructions on how to report a bug at http://bugs.php.net/how-to-report.php Your integer is larger than the 64bit signed range allows. PHP can not represent this as an int, and just as a float. ------------------------------------------------------------------------ [2014-02-13 11:19:30] sergey dot shilko at gmail dot com Trying to use: $encoded = json_encode($facebookIds, JSON_NUMERIC_CHECK); makes things even worse: samearray(2) { [0]=> float(4.8572380745623E+19) [1]=> string(20) "48572380745623087456" } array(2) { [0]=> float(4.8572380745623E+19) [1]=> float(4.8572380745623E+19) } It converts "big int" to float, but this is at least visible in var dump. ------------------------------------------------------------------------ [2014-02-13 11:12:17] sergey dot shilko at gmail dot com #$decoded = json_decode($encoded, false, 512, JSON_BIGINT_AS_STRING); Makes no difference. Test script output: array(2) { [0]=> float(4.8572380745623E+19) [1]=> string(20) "48572380745623087456" } array(2) { [0]=> float(4.8572380745623E+19) [1]=> string(20) "48572380745623087456" } Broken ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=66707 -- Edit this bug report at https://bugs.php.net/bug.php?id=66707&edit=1

« previous php.bugs (#195580) next »