PHP. Проверка корректности IP-адреса
![[info]](http://lj.rossia.org/img/userinfo.gif)
xxx.xxx.xxx.xxx
, где xxx
- десятеричное число от 0 до 255, а IP может быть записан и в виде шестнадцатеричных, и в виде восьмеричных чисел, и даже смешано. Также IP-адрес может быть неполным. Например, адрес 4.0.0.1
можно записать как 4.1
В наших скриптах корректность IP проверялась регулярным выражением, т.к. все равно им же производился поиск IP в полях
HTTP_*
, в которых IP может передаваться прокси-серверами.Но валидацию IP можно провести и без использования регулярных выражений. Другое дело, поиск без него уже не произведешь, и это может создать определенные проблемы, если прокси-сервер, например, будет передавать IP в виде шестнадцатеричных чисел или преобразовывать, где возможно, полные адреса в неполные.
В PHP 5.2.0 появилась функция
filter_var()
, которая позволяет проверять строки на соответствие разным форматам, не только IP, но и, например URL или e-mail. Для проверки IP она вызывается так:
filter_var($ip,FILTER_VALIDATE_IP);
где:
$ip
- строка, содержащая IP-адресFILTER_VALIDATE_IP
- встроенный фильтр для IP-адресаФункция возвращает
TRUE
, если строка прошла проверку, и FALSE
если нет.А не очень хорош способ тем, что валидацию проходят только IP, соответствующие формату "четыре десятеричных числа от 0 до 255, разделенных точкой", т.е. работает точно также, как и наша старая функция
Такое ощущение, что разработчики PHP пытаются избавить мир от зоопарка способов записи IP-адреса, и привести все, наконец, к единому знаменателю :)
Пример с использованием функции
filter_var
![[info]](http://lj.rossia.org/img/userinfo.gif)
inet_addr()
, но где ж я ее возьму-то в PHP, подумал я, и зря подумал. :) Функция ip2long($ip)
, которая использовалась для проверки попадания IP-адреса в определенный диапазон Копия ее аналог. Если переменная $ip
содержит корректный IP-адрес, то функция вернет целое число, если в IP-адресе ошибка, то функция вернет FALSE
или -1
. Примечание: Функция
ip2long()
возвратит FALSE для IP 255.255.255.255
в PHP 5 <= 5.0.2 и -1 в PHP 5 <=5.2.4 на 64-битных системах. Это было исправлено в PHP 5.2.5, теперь возвращается 4294967295. В 32-битных системах будет возвращено -1 из-за целочисленного переполнения.Так что проверку на корректность IP можно делать в функции-обертке, добавив код-заглушку для IP
255.255.255.255
:function IsIP($ip)
{
//преобразуем в нижний регистр, на случай шестнадцатиричных чисел
$ip=strtoupper($ip);
//ip2long в некоторых версиях php
//некорректно реагирует на адрес 255.255.255.255
//делаем небольшую заглушку
if ($ip == '255.255.255.255'||$ip == '0xff.0xff.0xff.0xff'||
$ip == '0377.0377.0377.0377')
{
return true;
}
$tolong=ip2long($ip);
if ($tolong == -1||$tolong===FALSE) return FALSE;
else return TRUE;
}
В PHP есть функция
long2ip()
, которая делает обратное преобразование, т.е. преобразует целое число в IP-адрес в привычном виде. Если их совместить, то можно преобразовывать неполные адреса в полные:function fulladdr($ip)
{
//преобразует неполные адреса в полные
//для информации
$tolong=ip2long($ip);
return long2ip ($tolong);
}
Пример работы скрипта:
isip.php?ip=4.1

Скрипт на GitHub
Внедрил последний метод в рабочие скрипты, залил на сервер, и оказалось, что метод не работает. Ну не то, чтобы не совсем не работает, а работает точно так же, как старая функция с регулярным выражением, т.е. возвращает
TRUE
только если IP-адрес записан в виде четырех десятеричных чисел от 0 до 255, разделенных точкой. Неполные адреса, или адреса в других системах счисления IP-адресами не считаются. Функция ip2long()
возвращает FALSE
, если ей скормить такой адрес. Уж не знаю, и сходу не нагуглил, отчего такая оказия, то ли такое поведение зависит от настроек PHP, то ли от сервера. На локальном сервере работало, а на том, который в интернете - перестало. Можно сказать, зря делал, но зато сделал валидацию IP без регулярного выражения.1. ip2long
2. Ещё раз о filter_var
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2018/07/26/php-p