PHP 里大整数类型转换问题

该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2014/10/19/big-integer-convert-in-php/

最近在写 tracker,遇到大整数类型转换溢出问题。具体表现为两个问题。

1. 大整数处理

问题源码如下:

1<?php
2#.....
3foreach (['uploaded', 'downloaded', 'port', 'left'] as $x)
4  $this->args[$x] = (int)$_GET[$x];
5#.....

乍看之下没问题,一开始测试也没问题。但当 uploadeddownloaded, left 超过 2GB 时,立即崩溃了。原因是 (int) 强制类型转换的实质是 intval 。如下代码:

1<?php
2echo intval('10000000000').'<br>'; # 2147483647
3echo (int)'10000000000'.'<br>'; # 2147483647
4echo (0 + '10000000000').'<br>'; # 10000000000 right~

问题解决,下面看第二个问题。

2. 32位有符号整数溢出

问题源码如下:

1<?php
2echo ip2long('255.255.255.255'); # echo -1

这个,正确的说,其实没错,但是如果我们希望用无符号32位整数表示,那么就郁闷了,尤其是数据库用 INT UNSIGNED 类型储存 IP 的时候。

解决方法很巧妙,源自php doc

1<?php
2echo sprintf("%u", ip2long('255.255.255.255'));
comments powered by Disqus