|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2014-02-13 11:07 UTC] sergey dot shilko at gmail dot com
Description: ------------ http://php.net/json_encode http://php.net/json_decode json_decode(json_encode(A)) != A json_encode + json_decode breaks large integers. Test script: --------------- <?php $facebookIds = array(48572380745623087456, '48572380745623087456'); $encoded = json_encode($facebookIds); $decoded = json_decode($encoded); var_dump($facebookIds); var_dump($decoded); if ($facebookIds != $decoded) { echo "\nBroken\n"; } PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 16:00:01 2025 UTC |
#$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" } BrokenTrying 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.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?