有没有一种简单的方法可以比较PHP中的IP?

时间:2019-02-12 10:58:51

标签: php ip

一方面,我有一个123.3.2.3这样的IP,我想将其与一系列允许的IP进行比较:

$allowedIps = ['123.*.*.*', '123.3.2.3', '123.3.2.3::1', '123.3.*.3']

在这种情况下,它应该匹配所有项目。

有没有一种简单的方法,而无需创建复杂的字符串比较算法?

1 个答案:

答案 0 :(得分:1)

如果您不打算将通配符用作123.3.2*.3,则该通配符将匹配123.3.20.3123.3.29.3之间的任何IP,那么下面的解决方案将可以正常工作。

遍历数组中的IP,如果其中存在通配符,则创建两个新IP-一个将通配符*替换为0,将另一个替换为255。上限。然后,使用ip2long()函数将其转换为整数,而不是IP字符串。循环对IP本身和数组中的值进行此操作。

然后只需要比较它们就可以了,实际上它在上限和下限之间。

如果字符串中没有通配符,请进行直接比较。

$allowedIps = ['123.2.*.*', '123.3.2.3', '123.3.*.3'];
$IP = '123.3.1.3';
$match = 0;

foreach ($allowedIps as $allowed) {
    // If there is no wildcard, we check for the specific IP instead, and not a range
    if (strpos($allowed, "*") !== false) {
        $lowest = str_replace("*", "0", $allowed);
        $highest = str_replace("*", "255", $allowed);

        if (ip2long($IP) >= ip2long($lowest) && ip2long($IP) <= ip2long($highest)) {
            echo "$IP matched $allowed";
            $match = 1;
            break;
        }
    } elseif (ip2long($IP) === ip2long($allowed)) {
        echo "Matched ".$allowed;
        $match = 1;
        break;
    }
}

可能甚至不需要检查通配符的条件,因为它不会替换任何内容,并且随后的if条件中的两个条件都为真。

公平警告,我尚未对此进行全面测试,在某些情况下,可能会失败。您最好在PHP之外执行此操作。