2009-05-27 38 views
1

我有一个脚本,通过一个IP数组循环,并检查客户IP对他们。根据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的一面呢?

回答

4

改变 “*” 到 “%”,那么做

SELECT 1 FROM filters WHERE '1.2.3.4' LIKE ip LIMIT 1 
+0

恕我直言,这是迄今为止最好的,最简单的答案 - 它不需要循环。 +1! – Dutchie432 2015-02-18 19:36:24

1

您可以使用思科的风格:

$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; 
} 
+0

这真的很有用,谢谢发布 – 2011-03-09 14:12:46

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; 
}