json_decode 整型溢出解决方法

编码过程中遇到个错误,就是在处理json时,数值较大的int值在解码后数据被损坏,比如:

 代码如下 复制代码

$array = array(
    "id1" => 2147483647,
    "id2" => 2147483648
);
$json = json_encode($array);
$out = json_decode($json, true);
var_dump($out);
理论上应该看到:

array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(2147483648)
}

但实际在我的电脑上却得到:

 代码如下 复制代码
array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(-2147483646)
}

这是由PHP整数值范围决定的,而这个范围依赖于操作系统。在32位操作系统中,PHP的整数最大值是2147483647,你可以通过输出PHP_INT_MAX看到。

一般情况下,你赋值一个很大的数,PHP会自动判定这个数值的范围并自动转换类型,如:

 代码如下 复制代码
$large_number = 2147483647;
var_dump($large_number);                     // int(2147483647)
 
$large_number = 2147483648;
var_dump($large_number);                     // float(2147483648)
 
$million = 1000000;
$large_number =  50000 * $million;
var_dump($large_number);                     // float(50000000000)

但是在json_decode方法中没有进行这种检测,这是PHP(旧版本)的bug,在5.3以后的版本,就不存在这个问题了。

如果你不想更新你的PHP,那还有个办法,就是将数字转为字符串。还是以上面的代码为例:

 代码如下 复制代码
$array = array(
    "id1" => 2147483647,
    "id2" => 2147483648
);
$json = json_encode($array);
 
$json = preg_replace('/("idd":)(d{9,})/i', '${1}"${2}"', $json);
 
$out = json_decode($json, true);
var_dump($out);

当然,这个怎么替换是按需而定的,而且需要比较细致的测试。

时间: 2024-10-12 07:15:17

json_decode 整型溢出解决方法的相关文章

C语言的数据类型整型溢出

什么是整型溢出 C语言的整型问题相信大家并不陌生了.对于整型溢出,分为无符号整型溢出和有符号整型溢出. 对于unsigned整型溢出,C的规范是有定义的--"溢出后的数会以2^(8*sizeof(type))作模运算",也就是说,如果一个unsigned char(1字符,8bits)溢出了,会把溢出的值与256求模.例如: unsigned char x = 0xff; printf("%dn", ++x); 上面的代码会输出:0 (因为0xff + 1是256,

mysql unsigned 用法及相减出现补数溢出解决方法_Mysql

unsigned 既为非负数,用此类型可以增加数据长度! 例如如果 tinyint最大是127,那 tinyint unsigned 最大 就可以到 127 * 2 unsigned 属性只针对整型,而binary属性只用于char 和varchar. 类型 说明 tinyint 非常小的整数 smallint 较小整数 mediumint 中等大小整数 int 标准整数 bigint 较大整数 float 单精度浮点数 double 双精度浮点数 decimal 一个串的浮点数 每种数值类型的

mysql unsigned 用法及相减出现补数溢出解决方法

unsigned   既为非负数,用此类型可以增加数据长度! 例如如果    tinyint最大是127,那    tinyint    unsigned    最大   就可以到    127 * 2 unsigned 属性只针对整型,而binary属性只用于char 和varchar. 类型 说明 tinyint 非常小的整数 smallint 较小整数 mediumint 中等大小整数 int 标准整数 bigint 较大整数 float 单精度浮点数 double 双精度浮点数 deci

jvm内存溢出解决方法(jvm内存溢出怎么解决)_java

java.lang.OutOfMemoryError: PermGen space 发现很多人把问题归因于: spring,hibernate,tomcat,因为他们动态产生类,导致JVM中的permanent heap溢出 .然后解决方法众说纷纭,有人说升级 tomcat版本到最新甚至干脆不用tomcat.还有人怀疑spring的问题,在spring论坛上讨论很激烈,因为spring在AOP时使用CBLIB会动态产生很多类. 但问题是为什么这些王牌的开源会出现同一个问题呢,那么是不是更基础的原

asp cint clng的范围与防止cint和clng的溢出解决方法大全_应用技巧

首先我们需要了解的是 cint范围 -32,768 到 32,767. clng范围 -2,147,483,648 到 2,147,483,647. cint与clng含义: 都可以强制将一个表达式转换成数据类型 cint与clng处理数据的范围: CInt Integer -32,768 至 32,767,小数部分四舍五入. CLng Long -2,147,483,648 至 2,147,483,647,小数部分四舍五入. 所谓溢出指的是超出处理数据的范围,下面代码是处理数据防止溢出的代码,

php中GBK/GB2312页面使用json_decode()中文丢失了解决方法

好像用json_decode()将数组/对象 序列化为JSON字符串的时候基本上只支持 UTF-8/ASCII编码.而我们有的站采用了GBK/GB2312编码,这个时候,直接使用json_encode/json_decode的时候就可能会出问题了.  代码如下 复制代码 <?php $json = '{"a":"中国人人"}'; var_dump(json_decode($json)); ?> 结果 {"text":null,&quo

asp cint clng的范围与防止cint和clng的溢出解决方法大全

首先我们需要了解的是 cint范围 -32,768 到 32,767. clng范围 -2,147,483,648 到 2,147,483,647. cint与clng含义: 都可以强制将一个表达式转换成数据类型 cint与clng处理数据的范围: CInt Integer -32,768 至 32,767,小数部分四舍五入. CLng Long -2,147,483,648 至 2,147,483,647,小数部分四舍五入. 所谓溢出指的是超出处理数据的范围,下面代码是处理数据防止溢出的代码,

PHP处理JSON字符串key缺少双引号的解决方法_php技巧

本文实例讲述了PHP处理JSON字符串key缺少引号的解决方法,分享给大家供大家参考之用.具体方法如下: 通常来说,JSON字符串是key:value形式的字符串,正常key是由双引号括起来的. 例如: <?php $data = array('name'=>'fdipzone'); echo json_encode($data); // {"name":"fdipzone"} print_r(json_decode(json_encode($data)

使用JAVA IP地址转成长整型方法时出现错误

java.lang.NumberFormatException: For input string: "0" 在使用JAVA IP地址转成长整型方法时出现此错误 这里对场景进行记录,以备日后遇到类似的错误,参考如何解决 错误输出: 错误原因:怀疑此处为"\0"字符 解决方法: 作者:csdn博客 微wx笑 更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/Java/