PHP网站焦特布尔地区移动数据下费率访问限制失效问题
解决移动数据下焦特布尔用户仍可查看费率的问题
问题根源
移动数据网络下,运营商通常通过NAT网关转发用户请求,导致$_SERVER['REMOTE_ADDR']获取的是运营商出口IP而非用户真实本地IP;仅通过城市名称Jodhpur匹配,可能存在重名城市或IP库数据过时的情况,导致定位不准确。
解决方案
- 获取用户真实IP:优先读取代理/网关传递的真实IP头,覆盖移动网络NAT场景
- 强化GeoIP匹配逻辑:同时匹配城市、地区(拉贾斯坦邦)和国家(印度),避免误判
- 更新GeoIP数据库:确保
GeoLite2-City.mmdb为最新版本,提升移动IP段定位准确率
修改后的代码
require 'vendor/autoload.php'; use GeoIp2\Database\Reader; use Exception; $databaseFile = 'GeoLite2-City.mmdb'; // 获取用户真实IP,兼容代理/移动网关场景 function getRealUserIp() { $ip = $_SERVER['REMOTE_ADDR']; // 检查常见代理头 if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip = trim(end($ipList)); } elseif (!empty($_SERVER['HTTP_X_REAL_IP'])) { $ip = $_SERVER['HTTP_X_REAL_IP']; } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } // 验证IP格式合法性 return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : $_SERVER['REMOTE_ADDR']; } // 更严谨的焦特布尔地区判断 function isVisitorFromJodhpur($ip, $databaseFile) { try { $reader = new Reader($databaseFile); $record = $reader->city($ip); // 同时匹配城市、地区、国家,避免重名城市误判 return ( $record->city->name === 'Jodhpur' && $record->mostSpecificSubdivision->name === 'Rajasthan' && $record->country->name === 'India' ); } catch (Exception $e) { // 定位失败时默认允许访问,避免误拦截 return false; } } $visitorIp = getRealUserIp(); $isFromJodhpur = isVisitorFromJodhpur($visitorIp, $databaseFile); ?> <?php if ($isFromJodhpur): ?> <h4>Sorry, access to this section is blocked for visitors from Jodhpur, Rajasthan, India.</h4> <?php else: ?> <h4><i class="fa fa-inr" aria-hidden="true"></i> <?php echo number_format($price1); ?></h4> <?php endif; ?>
额外注意事项
- 若网站使用CDN,需确保CDN已开启传递真实用户IP的功能,并对应读取CDN提供的IP头(如Cloudflare的
HTTP_CF_CONNECTING_IP) - 定期更新
GeoLite2-City.mmdb数据库,可通过MaxMind官方工具获取最新IP段数据
内容的提问来源于stack exchange,提问作者swati mathur
相关产品推荐
相关产品推荐

