我有一个循环遍历IP数组的脚本,并检查客户端IP。
//filter IP address list
$ip = array();
$ip[] = '10.10.5.*';
$ip[] = '234.119.260.65';
$ip[] = '234.119.254.2';
function testIP($ip){
//testing that correct IP address used
for($i=0, $cnt=count($ip); $i<$cnt; $i++) {
$ipregex = preg_replace(”/\./”, “\.”, $ip[$i]);
$ipregex = preg_replace(”/\*/”, “.*”, $ipregex);
if(preg_match('/'.$ipregex.'/', $_SERVER[REMOTE_ADDR])){
// apply filter
return true;
}
//do not apply filter
return false;
}
问题是,我希望我的IP地址列表在一个表中,我希望尽可能高效。我能看到这样做的唯一方法是SELECT *,并依次循环遍历每一个。任何人都可以看到更有效的方法吗?也许在MySQL方面呢?
答案 0 :(得分:4)
将“*”更改为“%”,然后执行
SELECT 1 FROM filters WHERE '1.2.3.4' LIKE ip LIMIT 1
答案 1 :(得分:1)
您可以使用cisco风格:
$ip[] = '10.10.5.0/24';
匹配功能贝娄
# Matches:
# xxx.xxx.xxx.xxx (exact)
# xxx.xxx.xxx.[yyy-zzz] (range)
# xxx.xxx.xxx.xxx/nn (nn = # bits, cisco style -- i.e. /24 = class C)
#
# Does not match:
# xxx.xxx.xxx.xx[yyy-zzz] (range, partial octets not supported)
function matchIP($range, $ip) {
$result = true;
if (preg_match("`^(\d{1,3}) \. (\d{1,3}) \. (\d{1,3}) \. (\d{1,3})/(\d{1,2})$`x", $range, $regs)) {
# perform a mask match
$ipl = ip2long($ip);
$rangel = ip2long($regs[1] . "." . $regs[2] . "." . $regs[3] . "." . $regs[4]);
$maskl = 0;
for ($i = 0; $i< 31; $i++) {
if ($i < $regs[5]-1) {
$maskl = $maskl + pow(2,(30-$i));
}
}
if (($maskl & $rangel) == ($maskl & $ipl)) $result = true;
else $result = false;
} else {
# range based
$maskocts = explode(".",$range);
$ipocts = explode(".",$ip);
# perform a range match
for ($i=0; $i<4; $i++) {
if (preg_match("`^\[(\d{1,3}) \- (\d{1,3})\]$`x", $maskocts[$i], $regs)) {
if ( ($ipocts[$i] > $regs[2]) || ($ipocts[$i] < $regs[1])) {
$result = false;
}
} else {
if ($maskocts[$i] != $ipocts[$i]) {
$result = false;
}
}
}
}
return $result;
}
答案 2 :(得分:1)
如果您的输入被保证为IP地址(您将其从$_SERVER
中拉出来,那么有效性检查或“理解”IP地址是无目的的):
//filter IP address list
$ip = array();
$ip[] = '10.10.5.*';
$ip[] = '234.119.260.65';
$ip[] = '234.119.254.2';
function testIP($ip){
//testing that correct IP address used
for($i=0, $cnt=count($ip); $i<$cnt; $i++) {
$ipregex = preg_replace("/\\./", "\\\\.", $ip[$i]);
$ipregex = preg_replace("/\\*/", "[.\\\\d]+", $ipregex);
if(preg_match("/^".$ipregex."$/", $_SERVER[REMOTE_ADDR])){
// apply filter
return true;
}
}
//do not apply filter
return false;
}