PHP 的 ip2long 是将 IP 位址转换为数值的 function.
ip2long() 转出来的数值应该都是正整数, 但是在某些机器转出负数, 刚开始以为是 PHP 版本问题, 后来做些测试, 确定是系统版本 32bits 和 64bits 的问题.
- 32 bits ip2long(): -2147483648 ~ 214748364764
- 64 bits ip2long(): 0 ~ 42949672945
测试
<?php
// 自己做转换, 这方法计算出来的数值是正确的.(32bits / 64bits 皆正确)
function iptolong($ip)
{
list($a, $b, $c, $d) = split('\.', $ip);
$ip_long = (($a * 256 + $b) * 256 + $c) * 256 + $d;return $ip_long;
}
?>
另外做测试, 于 return 值加上 intval(), 如下述:
<?php
// 这样子的数值就会产生负数.
function iptolong($ip)
{
list($a, $b, $c, $d) = split('\.', $ip);
$ip_long = (($a * 256 + $b) * 256 + $c) * 256 + $d;return intval($ip_long);
}
?>
intval 在 32 bits / 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.
另外做其它测试:
ip2long() 于 32bits 的系统测试
- ip2long(‘127.255.255.255’); // 2147483647 = 十进制的最大值
- ip2long(‘255.255.255.255’); // -1
- ip2long(‘255.255.255.254’); // -2
- ip2long(‘192.168.1.2’); // -1062731518
ip2long() 于 64bits 的系统测试
- ip2long(‘127.255.255.255’); // 2147483647 = 十进制的最大值
- ip2long(‘255.255.255.255’); // 4294967295
- ip2long(‘255.255.255.254’); // 4294967294
- ip2long(‘192.168.1.2’); // 3232235778
知道问题是 32bits 系统造成的, 就很好解决囉~
解法1 – 自己转换
<?php
function iptolong($ip)
{
list($a, $b, $c, $d) = split('\.', $ip);
return (($a * 256 + $b) * 256 + $c) * 256 + $d;
}
?>
解法2 – 转成二进制, 再转回十进制
<?php
// bindec 只吃 string, 回传 double
// decbin 会回传 string
echo bindec(decbin(ip2long('192.168.1.2'))); // 3232235778
// 此方法我也有点不太懂, 忘记从哪边看到的解法.
?>
解法3 – 官方建议的解法 (推荐用此方法)
<?php
// 直接印值, 使用 printf("%u")
printf("%u", ip2long('192.168.1.2')); // 3232235778// 回传值(于 function 或 echo 等), 使用 sprintf(“%u”)
echo sprintf(“%u”, ip2long(‘192.168.1.2’)); // 3232235778
?>
另外 于此篇 (PHP 的 ip2long 有 Bug) 看到的案例如下:
<?php
echo ip2long('058.99.11.1'); // null
echo ip2long('58.099.11.1'); // null
?>
若是会有这种情况, 用 解法1 即可解决.
from http://www.hksilicon.com/kb/cn/articles/4155/PHP-ip2long
真是瞎说,IPv4本身就是32位的,跟机器有什么关系?在32位平台上PHP默认的整数类型是32有符号整型。例如:A.B.C.D。当A大于127就为负数了,至于为什么,建议看看《tcp/ip协议详解》这本书,别在这里YY了。http://my.oschina.net/goal/blog/198049
跟机器有关的,操作系统是64位或32不同的,至少在centos6 x64 官方yum源里的php版本,var_dump(ip2long(‘222.73.1.1’)) 输出计算结果是 int(3729326337)
猜测:windows 64位下,如果安装x86版本的php,输出仍然是负数;x64 的php,输出应该也是正数。win下个人没有亲测。
btw,本文是当时在32位下做开发时,发现ip2long结果为负值结果,查资料学习后转来的。