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 оптимизированный
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
устарел)
Попробуйте вместо этого:
$ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR']));
sprintf запишет это как беззнаковое целое число.
$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 адрес.