json_decode和json_encode长整数而不丢失数据 [英] json_decode AND json_encode long integers without losing data
问题描述
如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的int不再存在任何问题,但是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')
之类的自定义类,并且您的自定义编码器会识别该类型并将其编码为JSON 9223372036854775808
值.
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.
这篇关于json_decode和json_encode长整数而不丢失数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!