PHP函数ip2long()返回值为负数的解决办法

PHP的ip2long 是将IP地址转换为数值的函数。

ip2long() 转出来的数值应该都是正整数,但是在某些机器转出负数, 刚开始以为是 PHP 版本问题, 后来做些测试, 确定是系统版本 32bits 和 64bits 的问题。

32 bits ip2long(): -2147483648 ~ 214748364764
64 bits ip2long(): 0 ~ 42949672945

测试代码:

1// 自己做转换, 这方法计算出来的数值是正确的.(32bits / 64bits 皆正确)
2function iptolong($ip){
3    list($a, $b, $c, $d) = split(".", $ip);
4    $ip_long = (($a * 256 + $b) * 256 + $c) * 256 + $d;
5    return $ip_long;
6}

另外做测试,在return值加上intval(), 如下述:

1// 这样子的数值就会产生负数.
2function iptolong($ip){
3    list($a, $b, $c, $d) = split(".", $ip);
4    $ip_long = (($a * 256 + $b) * 256 + $c) * 256 + $d;
5    return intval($ip_long);
6}

intval在32bits/64 bits最大值是不同的,于intval()里面有写到下述:

The maximum value depends on the system.
32 bit systems have a maximum signed integer range of -2147483648 to 2147483647.
So for example on such a system, intval("1000000000000") will return 2147483647.
The maximum signed integer value for 64 bit systems is 9223372036854775807.

另外做其它测试:

01//ip2long() 于 32bits 的系统测试
02ip2long("127.255.255.255"); // 2147483647 = 十进制的最大值
03ip2long("255.255.255.255"); // -1
04ip2long("255.255.255.254"); // -2
05ip2long("192.168.1.2"); // -1062731518
06ip2long() 于 64bits 的系统测试
07ip2long("127.255.255.255"); // 2147483647 = 十进制的最大值
08ip2long("255.255.255.255"); // 4294967295
09ip2long("255.255.255.254"); // 4294967294
10ip2long("192.168.1.2"); // 3232235778
11//知道问题是 32bits 系统造成的, 就很好解决囉~

解法1 - 自己转换

1function iptolong($ip){
2    list($a, $b, $c, $d) = split(".", $ip);
3        return (($a * 256 + $b) * 256 + $c) * 256 + $d;
4}

解法2 - 转成二进制, 再转回十进制

1// bindec 只吃 string, 回传 double
2// decbin 会回传 string
3echo bindec(decbin(ip2long("192.168.1.2"))); // 3232235778

解法3 - 官方建议的解法 (推荐用此方法)

1// 直接印值, 使用 printf("%u")
2printf("%u", ip2long("192.168.1.2")); // 3232235778
3// 回传值(于 function 或 echo 等), 使用 sprintf("%u")
4echo sprintf("%u", ip2long("192.168.1.2")); // 3232235778

[软件工程网注],关于第一种方法,从数值转换回IP可以使用下面的参考代码:

1function longtoip($num)  {
2    $d = $num%256;
3    $c = (($num-$d)/256)%256;
4    $b = (($num-($c*256)-$d)/(256*256))%256;
5    $a = (($num-($b*256*256)-$c*256-$d)/(256*256*256))%256;
6    return $a.".".$b.".".$c.".".$d;  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值