PHP如何判断IPv4地址是否在指定IP段内并实现拦截
拦截4.53.0.0/16网段IP的PHP实现方案
针对你遇到的垃圾IP骚扰问题,我们可以结合你提供的真实IP获取逻辑,加上网段判断规则来实现精准拦截。下面是具体的实现步骤和代码:
第一步:优化真实IP获取逻辑
原代码中HTTP_X_FORWARDED_FOR可能返回多个IP(比如经过多层代理的场景),我们需要取第一个有效IP,避免后续判断出错:
function getRealIpAddr() { // 检查客户端直连IP if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } // 处理代理传递的IP列表,取第一个有效IP elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ipList as $ipItem) { $ipItem = trim($ipItem); if (filter_var($ipItem, FILTER_VALIDATE_IP)) { $ip = $ipItem; break; } } } // 直接取服务器记录的连接IP else { $ip = $_SERVER['REMOTE_ADDR']; } // 最后验证IP合法性,防止非法值 return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : $_SERVER['REMOTE_ADDR']; } $userIp = getRealIpAddr();
第二步:实现网段拦截逻辑
这里提供两种判断方式,你可以根据需求选择:
方式1:直接检查IP前缀(简单直观)
适合固定网段的快速判断,直接验证IP的前两段是否为4.53:
$ipParts = explode('.', $userIp); // 确保IP格式正确,且前两段匹配目标网段 if (count($ipParts) === 4 && $ipParts[0] == '4' && $ipParts[1] == '53') { // 执行拦截操作:返回403、记录日志或终止请求 header('HTTP/1.1 403 Forbidden'); echo 'Access Denied: Your IP address is blocked due to malicious activity.'; // 可选:记录拦截日志到服务器 error_log("[Blocked IP] {$userIp} - " . date('Y-m-d H:i:s')); exit; }
方式2:IP转整数判断范围(灵活通用)
适合任意网段的判断,通过将IP转换为无符号整数,对比网段的起止范围:
// 将IP转换为无符号整数,避免负数问题 $userIpLong = sprintf('%u', ip2long($userIp)); // 计算目标网段的起止整数 $networkStart = sprintf('%u', ip2long('4.53.0.0')); $networkEnd = sprintf('%u', ip2long('4.53.255.255')); // 判断当前IP是否在目标网段内 if ($userIpLong >= $networkStart && $userIpLong <= $networkEnd) { header('HTTP/1.1 403 Forbidden'); echo 'Access Denied: Your IP address is blocked.'; error_log("[Blocked IP] {$userIp} - " . date('Y-m-d H:i:s')); exit; }
完整整合代码
把以上逻辑整合后,放在网站入口文件(比如index.php)的最顶部,确保在任何业务逻辑执行前完成拦截:
function getRealIpAddr() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ipList as $ipItem) { $ipItem = trim($ipItem); if (filter_var($ipItem, FILTER_VALIDATE_IP)) { $ip = $ipItem; break; } } } else { $ip = $_SERVER['REMOTE_ADDR']; } return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : $_SERVER['REMOTE_ADDR']; } $userIp = getRealIpAddr(); // 选择一种拦截方式即可,这里用前缀判断示例 $ipParts = explode('.', $userIp); if (count($ipParts) === 4 && $ipParts[0] == '4' && $ipParts[1] == '53') { header('HTTP/1.1 403 Forbidden'); echo 'Access Denied: Your IP address is blocked.'; error_log("[Blocked IP] {$userIp} - " . date('Y-m-d H:i:s')); exit; } // 后续业务逻辑代码...
注意事项
- 如果你的网站使用了CDN或反向代理,需要确保服务商正确传递真实IP到
HTTP_X_FORWARDED_FOR,否则可能误拦截代理服务器IP。 - 拦截后的操作可以按需调整:比如跳转到警告页面、返回JSON错误信息,或者仅记录日志不直接拦截(适合观察验证阶段)。
内容的提问来源于stack exchange,提问作者user285594
相关产品推荐
相关产品推荐

