php:ip2long返回负值

And*_* SK 15 php ip

function ip_address_to_number($IPaddress) { 
     if(!$IPaddress) {
      return false;
     } else {
      $ips = split('\.',$IPaddress);
      return($ips[3] + $ips[2]*256 + $ips[1]*65536 + $ips[0]*16777216);
     }
}
Run Code Online (Sandbox Code Playgroud)

该函数执行与php捆绑函数ip2long相同的代码.但是,当我打印这2个值时,我得到2个不同的回报.为什么?(我在wamp环境中使用php 5.2.10).

ip2long('200.117.248.17'); //returns **-931792879**

ip_address_to_number('200.117.248.17'); // returns **3363174417**
Run Code Online (Sandbox Code Playgroud)

应用并继续在这里: 根据我的IP显示我的国家,mysql优化

web*_*ave 32

试试这个:

$ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR']));
Run Code Online (Sandbox Code Playgroud)

然后sprintf将其写为无符号整数.

  • 不是真的,克里斯蒂安.它不仅仅是按位运算,它是数组创建/访问加上按位运算.无论如何,这是一个微观优化,任何人都很难在两者之间显示任何不可忽视的速度差异.使用哪种方法更易读/舒适. (2认同)

Art*_*cto 10

glopes@nebm:~$ php -r "printf('%u', -931792879);"
3363174417

你去吧 我的猜测是你在一个32位整数的系统上,你ip_address_to_number实际上正在返回一个浮点数.

你看,使用32位整数,你的最大正整数是(2^31) - 1 = 2 147 483 647,所以整数环绕.

如果要模仿PHP函数的行为,请执行以下操作:

function ip_address_to_number($IPaddress) { 
 if(!$IPaddress) {
  return false;
 } else {
  $ips = split('\.',$IPaddress);
  return($ips[3] | $ips[2] << 8 | $ips[1] << 16 | $ips[0] << 24);
 }
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一下,split已被弃用)

  • 先生,是我(今天)的个人英雄.谢谢! (2认同)

Mar*_*ker 6

  $ips[3]                             = 17
+ $ips[2] * 256 = 248 * 256           = 63488
+ $ips[1] * 65536 = 117 * 65536       = 7667712
+ $ips[0] * 16777216 = 200 * 16777216 = 3355443200
                                      = 3363174417
Run Code Online (Sandbox Code Playgroud)

PHP最大整数值(32位)是2147483647,<3363174417

从ip2long()PHP手册页引用

注意:由于PHP的整数类型是有符号的,并且许多IP地址将导致负整数,因此需要使用sprintf()或printf()的"%u"格式化程序来获取无符号IP地址的字符串表示形式.

  • @Artefacto:不,问题是"为什么PHP开发人员不解决这个问题,而且没有'ip2long`返回负值?" (4认同)