PHP开发:根据IP地址获取所在地,限制特定城市禁止访问
网站有时候需要限制特定城市身份不让访问,就可以ii根据客户端IP地址获取所属城市进而进行限制访问。
1.技术点在于解决如何获取客户端地址,因为有可能客户端使用了代理模式,那么就需要获取真实IP地址。
2.根据IP地址使用百度开放API和腾讯地图API获取IP所在城市,限制访问。
具体实现方式:
获取真实IP地址
主要就是判断三个值,存在即可
function get_client_ip() { $ip_address = ''; if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip_list = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $ip_address = trim(end($ip_list)); } else if (isset($_SERVER['HTTP_CLIENT_IP']) && !empty($_SERVER['HTTP_CLIENT_IP'])) { $ip_address = $_SERVER['HTTP_CLIENT_IP']; } else if (isset($_SERVER['REMOTE_ADDR']) && !empty($_SERVER['REMOTE_ADDR'])) { $ip_address = $_SERVER['REMOTE_ADDR']; } return $ip_address;}
根据IP地址获取城市地区
如果客户端用了代理反向代理,IP地址可能会有端口号,所以需要处理掉端口号。
下面使用的是腾讯地图的API,需要去申请一个key,免费的申请地址。获取的IP信息根据结构获取IP的省份和城市信息返回即可。
https://lbs.qq.com/
function get_city() { $realip = get_client_ip(); $realip = preg_replace('/:\d+/', '', $realip); //去除端口号 $key = '你的key'; $url="https://apis.map.qq.com/ws/location/v1/ip?ip=".$realip."&key=".$key; // 使用curl $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); curl_close($curl); // 解码JSON数据为PHP数组 $data = json_decode($response, true); //true解析成 数据结构 $data = $data['result']['ad_info']['province'].$data['result']['ad_info']['city']; return $data;}
还有一个方式是使用百度开放API,这个不需要申请账号,直接构战URL地址就行,具体使用哪个看识别正确率吧,在我试验两个没啥区别,两者的区别在于返回的数据结构会有不一样,所以需要不同的索引值获取到城市信息。
http://opendata.baidu.com/api.php?query=ip地址&co=&resource_id=6006
function get_city(){ $realip = get_client_ip(); $realip = preg_replace('/:\d+/', '', $realip); //去除端口号 $api = "http://opendata.baidu.com/api.php?query=" .$realip. "&co=&resource_id=6006"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $api); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3); $handles = curl_exec($ch); curl_close($ch); $handles = iconv('GB2312', 'UTF-8', $handles); $arr = json_decode($handles, true); return $arr["data"][0]["location"];}
调用获取的城市处理特定限制禁止访问
这里设置了深圳地区不让访问,使用php返回头部信息404或者其他错误信息。
$local = get_city();if (strpos($local,"深圳") !==false) { header('HTTP/1.1 404 Not Found'); exit();}
页面URL不跳转显示错误
如果在服务器上设置了404或者于上面的对应的错误页面那么就可以实现URL地址不改变返回错误页面,下面是nginx配置404错误,一般宝塔都带有只需要把前面的#注释解除即可
#ERROR-PAGE-START 错误页配置,可以注释、删除或修改 error_page 404 /404.html;

当然也可以弄个特定的页面,比如给个提示啥的,提示该城市禁止访问等,返回给客户端就行了。