2009-05-27 34 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; 
}