【问题标题】:How can I simply validate whether a string is a valid IP in PHP?如何简单地验证字符串是否是 PHP 中的有效 IP?
【发布时间】:2015-09-03 00:16:59
【问题描述】:

使用 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 吗?

【问题讨论】:

  • 请改写你的问题。目前它在语法上是乱码,并且还可以从使用富文本格式化功能(例如代码格式化)中受益。此外,使用省略号(“...”)意味着不耐烦,这意味着权利,好像我们现在应该已经为您解决了您的问题。可能想重温一下。
  • 是的,实际上我是这个网站的新手,所以我没有更多的知识,但我认为这是一个很棒的网站
  • 如果我想删除我的这个问题,那么它是怎么可能的,因为我有这个问题的答案
  • @harison - 当你得到答案时,你不会删除你的问题,而是让其他人从知识中受益。
  • @harison: 询问、获得答案、删除 --- 在这里的行为不正确;-)

标签: php validation


【解决方案1】:

试试filter_var

示例:

if(filter_var('127.0.0.1', FILTER_VALIDATE_IP) !== false) {
    // is an ip
} else {
    // is not an ip
}

如果您现在有 foo127.0.0.bla 或类似的字符串,filter_var 将返回 false10.1.10.10::1 等有效 IP 被视为有效。

通知

您还必须检查!== false,因为filter_var 返回的值是否有效,false 如果无效(例如filter_var("::1", FILTER_VALIDATE_IP) 将返回::1true)。

标志

您还可以使用以下一些标志:

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)

如果$ip127.0.0.1,该函数将返回false

注意尴尬的::1 可以用于FILTER_FLAG_NO_PRIV_RANGE,但127.0.0.1 不行。

【讨论】:

  • 自从我发现了 filter_var 我不想错过它。这是验证 IP、电子邮件地址等的可靠方法(据我所知)。
  • 这对我来说效果很好。希望有更多过滤器用于其他网络信息验证。
【解决方案2】:
$valid = ip2long($ip) !== false;

【讨论】:

  • @Ozh: 200 实际上是技术上有效的 IP 地址 0.0.0.200。有一些限制不允许你在现实生活中使用它(就像很多其他的一样),但它仍然是一个有效的 IP
  • 实际上,ip2long 对像“192.168.0355.24”这样的字符串返回true,这不是一个有效的ip,是吗?不过,这可能是一个错误,因为使用输入字符串“192.168.355.24”,函数会按预期返回 false。但是,应该小心使用该功能。 iNaD 的回答提供了更可靠的结果。
  • @para: 为什么它不是一个有效的 IP?它一个有效的 IP。感谢您的反对。当你意识到你错了 - 请撤消它。谢谢你。 PS:即使2130706433 是合法IP,尝试ping 一下。 PPS:如果您仍然不相信 - 打开 0313.109.178.99 并查看它是谷歌
  • @zerkms 好吧,filter_var 确实过滤掉了它,所以我想你想要的结果肯定有一些差异。如果它是一个有效的 IP,你能解释一下为什么 filter_var 过滤掉它吗?我将删除反对票(尽快,我现在收到一个错误,因为我在 1 小时前投票),但如果你能解释一下会很好:)
  • @zerkms 刚刚发现这样的 IP 的某些部分会被解释为八进制数,而不是十进制数,所以我想这解释了为什么它可以被 ping 通。好的! :) 可能是因为很少使用八进制数(前导零),所以我认为前导零什么都不做,实际上它将以下内容描述为八进制。
【解决方案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;
}

【讨论】:

  • 用于测试IP的每一部分是否在正确的范围内。
  • 不,但这是您可以做到的方式之一。
【解决方案4】:

iNaD 是对的,filter_var() 版本是最好的版本 - ip2long() 真的 不是那种故障保存。试着放入一些奇怪的东西,自己看看。我进行了性能检查,filter_var 比常见的正则表达式版本快得多。

【讨论】:

  • 这样的东西可能应该放在评论中。这不是答案。
  • 对不起,但这不是像@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) && 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

    【讨论】:

      猜你喜欢
      • 2015-08-06
      • 1970-01-01
      • 2011-02-08
      • 2019-11-15
      • 1970-01-01
      • 2021-01-26
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多