json_decode AND json_encode 长整数而不丢失数据
如 PHP 文档中所述,当 json_decode
处理包含长整数的数据结构时,它们将被转换为浮点数.解决方法是使用 JSON_BIGINT_AS_STRING
,将它们保留为字符串.当 json_encode
输入这些值时,JSON_NUMERIC_CHECK
会将这些数字编码回大整数:
As noted in the PHP documentation, when json_decode
ing a data structure containing long integers, they'll be converted to floats. The workaround is to use JSON_BIGINT_AS_STRING
, which preserves them as strings instead. When json_encode
ing such values, JSON_NUMERIC_CHECK
will encode those numbers back into large integers:
$json = '{"foo":283675428357628352}';
$obj = json_decode($json, false, JSON_BIGINT_AS_STRING);
$json2 = json_encode($obj, JSON_NUMERIC_CHECK);
var_dump($json === $json2); // true
使用此方法正确往返数据很容易出错.如果一个属性包含 '123'
,一个数字字符串,应该保持一个字符串,它将被编码为一个整数.
Using this method for a correct roundtrip of the data is prone to errors. If a property contains '123'
, a numeric string which should stay a string, it will be encoded to an integer.
我想从服务器获取一个对象,修改一个属性,然后把整个数据结构放回去.我需要保留原始类型.除了我正在操作的属性之外,我不想维护其他属性.
I want to get an object from the server, modify one property and than put the entire data structure back. I need to preserve the original types. I don't want to maintain properties other than the one I'm manipulating.
有什么真正的解决方法吗?PHP 对大整数不再有任何问题,但 json_decode
例程似乎已经过时了.
Is there any real workaround for this? PHP does not have any issues with big ints anymore, but the json_decode
routine seems to be outdated.
推荐答案
只要你的 PHP 版本实际上可以处理大整数,这意味着如果你运行的是 64 位版本的 PHP (在一些 Windows以外),json_decode
没问题:
As long as your PHP version can actually handle large integers, meaning if you're running a 64-bit version of PHP (on something other than Windows), json_decode
has no problem with it:
$json = '{"foo":9223372036854775807}';
$obj = json_decode($json);
$json2 = json_encode($obj);
var_dump(PHP_INT_MAX, $obj, $json2);
int(9223372036854775807)
object(stdClass)#1 (1) {
["foo"]=>
int(9223372036854775807)
}
string(27) "{"foo":9223372036854775807}"
如果您需要处理的整数值确实超过了 PHP 的 PHP_INT_MAX
,那么您只是 不能 以 PHP 原生类型表示它们.因此,您无法解决这个难题;您不能使用本机类型来跟踪正确的类型,也不能替换其他类型(例如字符串而不是整数),因为在编码回 JSON 时会产生歧义.
If the integer values you need to handle do exceed PHP's PHP_INT_MAX
, you simply cannot represent them in PHP native types. So there's no way around the conundrum you have; you cannot use native types to track the correct type, and you cannot substitute other types (e.g. strings instead of integers), because that's ambiguous when encoding back to JSON.
在这种情况下,您必须发明自己的机制来跟踪每个属性的正确类型,并使用自定义编码器/解码器处理此类序列化.例如,您需要编写一个自定义 JSON 解码器,该解码器可以解码为自定义类,如 new JsonInteger('9223372036854775808')
,您的自定义编码器会识别此类型并将其编码为 JSON9223372036854775808
值.
In this case you will have to invent your own mechanism of tracking the correct types for each property and handle such serialisation with a custom encoder/decoder. For example, you'd need to write a custom JSON decoder which can decode to a custom class like new JsonInteger('9223372036854775808')
, and your custom encoder would recognise this type and encode it to a JSON 9223372036854775808
value.
PHP 中没有内置这样的东西.
There's no such thing built into PHP.
相关文章