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("",
    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).

3 Replies to “IP Matching With CIDR Notation In PHP”

  1. Thanks for the excellent function, Bill! I also tried some functions from http://www.php.net; some of them I could tell wouldn’t always work, and some seemed like the would until I tested them. I guess when all else fails you just need to go back to the basics of converting bitmasks and IP addresses. I appreciate the commented code! You will find this code in Tera-WURFL 2.1.1 (TeraWurflWebservice.php) once I release it!

  2. I wish I could claim it as my own, but the code and comments are both from the zend site. I posted this only to make it easier for people to find the solution. Glad it helped!

  3. You’re darn right about not being able to find an answer, no matter how hard you Google – I’ve spent nearly a week trying out various scripts, with no luck until I found this one. Thanks a million.

    The crucial info was to express the array with quotes around each CIDR, and once I did this with other solutions found where you mentioned, many of them worked. Unfortunately they just said ‘use an array’ without showing exactly how.

Comments are closed.