面對惡意刷單、爬蟲騷擾或特定區域合規需求,開發者常需在 PHP 層面實現:
X-Forwarded-For、Client-IP)獲取真實客戶端 IPfunction getRealIp(): string {
$headers = [
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'REMOTE_ADDR'
];
foreach ($headers as $header) {
$val = getenv($header) ?: ($_SERVER[$header] ?? '');
if ($val && strcasecmp($val, 'unknown') !== 0) {
// X-Forwarded-For 可能包含多個 IP,取第一個非未知
$ips = array_map('trim', explode(',', $val));
foreach ($ips as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
}
}
}
return '127.0.0.1'; // fallback
}
$blockedIps = ['192.168.1.88', '10.0.0.5'];
if (in_array(getRealIp(), $blockedIps)) {
header('HTTP/1.1 403 Forbidden');
exit('Access Denied');
}
使用 ip2long 與位運算判斷 IP 是否落在 CIDR 區間,支援 IPv4:
function ipInCidr(string $ip, string $cidr): bool {
[$range, $netmask] = explode('/', $cidr);
$mask = ~((1 << (32 - $netmask)) - 1);
return (ip2long($ip) & $mask) === (ip2long($range) & $mask);
}
// 使用示例
$blockedCidrs = ['192.168.0.0/16', '10.0.0.0/8', '172.16.0.0/12'];
$clientIp = getRealIp();
foreach ($blockedCidrs as $cidr) {
if (ipInCidr($clientIp, $cidr)) {
header('Location: https://example.com/blocked.html');
exit;
}
}
若無需完整 CIDR,僅匹配前綴(如 192.168.*.*),可拆分八位組比對:
$ipSeg = explode('.', getRealIp());
if ($ipSeg[0] === '192' && $ipSeg[1] === '168') {
// 屬於 192.168.0.0/16
header('HTTP/1.1 403 Forbidden');
exit;
}
X-Forwarded-For 可偽造,高安全場景需結合可信代理鏈驗證。