#php #validation
#php #проверка
Вопрос:
Используя PHP, как мне проверить, является ли строка допустимым IP?
Примеры допустимых строк:
- 192.158.5.95
- 121.212
- 12.12.12.204
Примеры недопустимых строк:
- 121
- 10 12 12 (без точек)
Мой текущий скрипт использует этот код, но этого недостаточно для моих нужд:
if(strpos($input, '.') !== false)
{
// There is a period
}
else
{
// No Period
}
Таким образом, может кто-нибудь, пожалуйста, посоветовать, как я могу подтвердить, что строка является допустимым IP?
Комментарии:
1. Пожалуйста, перепишите свой вопрос. На данный момент это грамматическая тарабарщина, и также было бы полезно использовать функциональность форматирования расширенного текста (например, форматирование кода). Кроме того, использование многоточия («…») подразумевает нетерпение, которое подразумевает право, как будто мы уже должны были решить вашу проблему за вас к настоящему времени. Возможно, захочется вернуться к этому.
2. на самом деле я новичок на этом сайте, поэтому у меня нет дополнительных знаний, но я думаю, что это отличный сайт
3. если я хочу удалить свой этот вопрос, то как это возможно, потому что у меня есть ответ на этот вопрос
4. @harison — Вы не удаляете свой вопрос, когда получаете ответ, вы оставляете его для других, чтобы извлечь выгоду из знаний.
5. @harison: спросить, получить ответ, удалить — это неправильный способ поведения здесь 😉
Ответ №1:
Попробуйте это с помощью filter_var
Пример:
if(filter_var('127.0.0.1', FILTER_VALIDATE_IP) !== false) {
// is an ip
} else {
// is not an ip
}
Если у вас теперь есть строка, подобная foo
, 127.0.0.bla
или аналогичная, filter_var
вернется false
. Допустимые IP-адреса, такие как 10.1.10.10
, ::1
, считаются допустимыми.
УВЕДОМЛЕНИЕ
Также вы должны проверить на !== false
, потому что filter_var
возвращает значение, если оно допустимо и false
если это не так (например, filter_var("::1", FILTER_VALIDATE_IP)
вернет ::1
, не true
).
Флаги
Вы также могли бы использовать некоторые из следующих флагов:
FILTER_FLAG_IPV4 (Фильтр для IPV4)
FILTER_FLAG_IPV6 (Фильтр для IPV6)
FILTER_FLAG_NO_PRIV_RANGE (Запретить IP-адреса из частного диапазона)
FILTER_FLAG_NO_RES_RANGE (Запретить IP-адреса из зарезервированного диапазона)
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)
Если $ip
это 127.0.0.1
, функция вернет false
.
Notice Неуклюже ::1
подходит для FILTER_FLAG_NO_PRIV_RANGE
, но 127.0.0.1
нет.
Комментарии:
1. С тех пор, как я обнаружил filter_var, я не хочу это пропустить. Это надежный способ (насколько я могу сказать) проверки IP-адресов, адресов электронной почты и т.д.
2. У меня это хорошо сработало. Хотелось бы, чтобы было больше фильтров для проверки другой сетевой информации.
Ответ №2:
$valid = ip2long($ip) !== false;
Комментарии:
1. @Ozh:
200
на самом деле это технически допустимый IP-адрес0.0.0.200
. Существуют ограничения, которые не позволят вам использовать его в реальной жизни (как и многие другие), но это все равно допустимый IP2. На самом деле, ip2long возвращает true для строк типа «192.168.0355.24», что сейчас не является допустимым ip, не так ли? Это может быть ошибкой, хотя, поскольку с входной строкой «192.168.355.24» функция возвращает false, как и ожидалось. Однако следует быть осторожным, используя функцию такой, какая она есть. Ответ iNaD обеспечивает более надежный результат.
3. @para: почему это не допустимый IP? Это ЯВЛЯЕТСЯ допустимым IP. Спасибо за понижение. Когда вы поймете, что ошибаетесь — пожалуйста, отмените это. Спасибо. PS: даже если
2130706433
это допустимый IP, попробуйте пропинговать его. PPS: если вы все еще не верите — откройте 0313.109.178.99 и посмотрите, что это google4. @zerkms Ну, filter_var отфильтровывает это, поэтому я предполагаю, что должна быть какая-то разница в том, какой результат вы хотите ожидать. Если это допустимый IP, можете ли вы объяснить, почему filter_var отфильтровывает его? Я удалю отрицательный голос (как только это будет возможно, сейчас я получаю сообщение об ошибке, потому что я голосовал 1 час назад), но было бы неплохо, если бы вы могли объяснить 🙂
5. @zerkms только что выяснил, что части такого IP затем интерпретируются как восьмеричные, а не десятичные числа, так что, я думаю, это объясняет, почему его можно пинговать. ХОРОШО! 🙂 Может быть, потому, что редко используются восьмеричные числа (начальный ноль), поэтому я подумал, что начальный ноль просто ничего не делает, где на самом деле он описывает следующее как восьмеричное.
Ответ №3:
На всякий случай, если есть кто-то, кто не хочет использовать функцию ip2long, вот простая функция (Идея взята из класса в osTicket):
function is_ip( $ip = null ) {
if( !$ip or strlen(trim($ip)) == 0){
return false;
}
$ip=trim($ip);
if(preg_match("/^[0-9]{1,3}(.[0-9]{1,3}){3}$/",$ip)) {
foreach(explode(".", $ip) as $block)
if($block<0 || $block>255 )
return false;
return true;
}
return false;
}
Комментарии:
1. Он используется для проверки, находится ли каждая часть IP в правильном диапазоне.
2. Нет, но это один из способов, которыми вы можете это сделать.
Ответ №4:
К сожалению, версия filter_var() является лучшей — ip2long() действительно не настолько безотказна. Просто попробуйте ввести некоторые странные вещи и убедитесь сами. Я выполнил проверку производительности, и filter_var работает намного быстрее, чем обычные версии регулярных выражений.
Комментарии:
1. Что-то вроде этого, вероятно, следует добавить в комментарий. Это не ответ.
2. Извините, но это не реальный ответ, как сказал @php_coder_3809625. Итак, понижение.
Ответ №5:
<?php
$ip = "192.168.0.1";
if(filter_var($ip, FILTER_VALIDATE_IP))
{
echo "IP is valid";
} else
{
echo "IP is not valid";
}
?>
Ответ №6:
Если @Tomgrohl вызвал регулярные выражения, вы можете сделать это в одной строке:
function is_ip($ip) {
return is_string($ip) amp;amp; preg_match('/^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5]).([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5]).([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5]).([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5])$/');
}
Объяснение:
/ // regex delimiter
( // start grouping
[0-9] // matches from 0 to 9
| // or
[1-9][0-9] // matches from 10 to 99
| // or
1[0-9]{2} // matches from 100 to 199
| // or
2[0-5][0-5] // matches from 200 to 255
) stop grouping
. // matches the dot
// the rest (same) of the numbers
/ regex delimiter
Онлайн-тестер:https://regex101.com/r/eM4wB9/1
Примечание: он соответствует только ipv4