一方面,我有一个123.3.2.3
这样的IP,我想将其与一系列允许的IP进行比较:
$allowedIps = ['123.*.*.*', '123.3.2.3', '123.3.2.3::1', '123.3.*.3']
在这种情况下,它应该匹配所有项目。
有没有一种简单的方法,而无需创建复杂的字符串比较算法?
答案 0 :(得分:1)
如果您不打算将通配符用作123.3.2*.3
,则该通配符将匹配123.3.20.3
和123.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之外执行此操作。