php: ip2long возвращая отрицательный val

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);
     }
}

та функция выполняет тот же код как php связанная функция ip2long. однако, когда я печатаю эти 2 значения, я получаю 2 различных возврата. почему? (im использующий php 5.2.10 на wamp среде).

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

ip_address_to_number('200.117.248.17'); // returns **3363174417**

Примененный и продолжался здесь: Показывая мою страну на основе моего IP, mysql оптимизированный

15
задан Community 23 May 2017 в 11:47
поделиться

3 ответа

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);
 }
}

(кстати, split устарел)

10
ответ дан 1 December 2019 в 00:23
поделиться

Попробуйте вместо этого:

$ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR']));

sprintf запишет это как беззнаковое целое число.

32
ответ дан 1 December 2019 в 00:23
поделиться
  $ips[3]                             = 17
+ $ips[2] * 256 = 248 * 256           = 63488
+ $ips[1] * 65536 = 117 * 65536       = 7667712
+ $ips[0] * 16777216 = 200 * 16777216 = 3355443200
                                      = 3363174417

Максимальное целочисленное значение PHP (32-битное) - 2147483647, что составляет <3363174417

Цитата из страницы руководства ip2long () PHP

Примечание. Поскольку целочисленный тип PHP подписан, и многие IP-адреса будут приводит к отрицательным целым числам, вам нужно использовать средство форматирования "% u" функции sprintf () или printf (), чтобы получить строку представление беззнакового IP адрес.

6
ответ дан 1 December 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: