简体   繁体   中英

How can I simply validate whether a string is a valid IP in PHP?

Using PHP, how do I validate that a string is a valid IP?

Examples of valid strings:

  • 192.158.5.95
  • 121.212
  • 12.12.12.204

Examples of invalid strings:

  • 121
  • 10 12 12 (no dots)

My current script uses this code, but this is insufficient for my needs:

if(strpos($input, '.') !== false)
{    
  // There is a period 
} 
else 
{     
  // No Period 
} 

As such, can someone please advise how I can validate that a string is a valid IP?

Try it with filter_var

Example:

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

If you now have a string like foo , 127.0.0.bla or similar, filter_var will return false . Valid IPs like 10.1.10.10 , ::1 are considered as valid.

Notice

Also you have to check on !== false , because filter_var returns the value, if it is valid and false if it isn't (eg filter_var("::1", FILTER_VALIDATE_IP) will return ::1 , not true ).

Flags

You could also use some of the following flags:

FILTER_FLAG_IPV4 (Filter for IPV4)

FILTER_FLAG_IPV6 (Filter for IPV6)

FILTER_FLAG_NO_PRIV_RANGE (Disallow IPs from the private range)

FILTER_FLAG_NO_RES_RANGE (Disallow IPs from the reserved range)

filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)

If $ip is 127.0.0.1 the function will return false .

Notice Awkwardly ::1 is ok for FILTER_FLAG_NO_PRIV_RANGE , but 127.0.0.1 isn't.

$valid = ip2long($ip) !== false;

Just in case there's anyone that doesn't want to use the ip2long function, here is a simple function (Idea taken from a class in 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;
}
<?php
$ip = "192.168.0.1";    
if(filter_var($ip, FILTER_VALIDATE_IP))
{
  echo "IP is valid";
} else
{
  echo "IP is not valid";
}
?> 

If @Tomgrohl brought up regexes, you can do it in one line:

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])$/');
}

Explanation:

/ // 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

Online tester: https://regex101.com/r/eM4wB9/1
Note: it only matches ipv4

iNaD ist right, the filter_var() version is the best one - ip2long() is really not that failsave. Just try to put in some strange things and see for yourself. I did a performace-check and filter_var is pretty much faster than the common regex versions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM