後台設定黑名單/白名單,支援三種格式:單一 IP(`192.168.1.1`)、IP 範圍(`192.168.1.10-192.168.1.20`)、CIDR(`192.168.1.0/24`)。初始化時讀取規則,每請求檢查客戶端 IP 是否命中。
<?php
/**
* IP 地址匹配檢查
* @param string $network 規則:單一IP / IP範圍 / CIDR
* @param string $ip 待檢查 IP
* @return bool
*/
function netMatch($network, $ip) {
$network = trim($network);
$ip = trim($ip);
// IP 範圍:174.129.0.0 - 174.129.255.255
if (($pos = strpos($network, '-')) !== false) {
$from = ip2long(substr($network, 0, $pos));
$to = ip2long(substr($network, $pos + 1));
$ipLong = ip2long($ip);
return ($ipLong >= $from && $ipLong <= $to);
}
// CIDR:174.129.0.0/16
if (strpos($network, '/') !== false) {
list($net, $mask) = explode('/', $network);
$netLong = ip2long($net);
$ipLong = ip2long($ip);
// 計算網路遮罩:~((1 << (32 - $mask)) - 1)
$maskLong = ~((1 << (32 - $mask)) - 1);
return (($ipLong & $maskLong) == $netLong);
}
// 單一 IP
return $network === $ip;
}
// 測試
var_dump(netMatch('174.129.0.0 - 174.129.255.255', '174.129.1.31')); // true
var_dump(netMatch('174.129.0.0/16', '174.139.1.31')); // false
var_dump(netMatch('174.129.1.32', '174.129.1.31')); // false
?>
/24 → 255.255.255.0 → 二進位 11111111.11111111.11111111.00000000
IP & 遮罩 = 網路位址 → 比較是否等於規則網路位址
參考來源:PHP.net ip2long 註釋 #70055, #82397。