IP Matching With CIDR Notation In PHP

Sometimes you can’t find an answer, no matter how hard you Google. I consider myself lucky to have found this answer!

The Problem: You have a list of IP ranges in CIDR notation. You need to take visiting IPs and evaluate if they are within this list of allowed addresses. And, you need to do it in PHP.

The Answer: Load your CIDR list into an array and evaluate each visiting IP with the following function (found here)…

function ipfilter($ip) {
    $source = array("10.0.0.0/8",
        "192.168.1.1/32",
        "127.0.0.0/8");
    foreach ($source as $line) {
    

        // Get the base and the bits from the CIDR
        list($base, $bits) = explode('/', $line);
       
        // Now split it up into it's classes
        list($a, $b, $c, $d) = explode('.', $base);
       
        // Now do some bit shifting/switching to convert to ints
        $i    = ($a << 24) + ($b << 16) + ( $c << 8 ) + $d;
        $mask = $bits == 0 ? 0: (~0 << (32 - $bits));
       
        // Here's our lowest int
        $low = $i & $mask;
       
        // Here's our highest int
        $high = $i | (~$mask & 0xFFFFFFFF);
       
        // Now split the ip we're checking against up into classes
        list($a, $b, $c, $d) = explode('.', $ip);
       
        // Now convert the ip we're checking against to an int
        $check = ($a << 24) + ($b << 16) + ( $c << 8 ) + $d;
       
        // If the ip is within the range, including highest/lowest values,
        // then it's witin the CIDR range
        if ($check >= $low && $check <= $high) {
            return 1;
        }
    }
    return 0;

}

Is it efficient? I don’t know. Does it work? Yes it does. And thats more than I can say about other solutions to this problem that I found (here and elsewhere).