PHP 获取IP地址位置信息「聚合数据API」
聚合数据 提供了【查询IP所属区域】的服务接口,只需要以 GET 请求的方式向 API 传入 IP地址 和 APPKEY 即可获得查询结果。
这里的难点主要在于如何通过PHP获取客户端IP地址,以及如何以GET方式向服务接口发送请求和获取相应。
====================获取IP地址=====================
通常情况下只需要 $_SERVER['REMOTE_ADDR'] 就可以获取客户端IP地址。
不过有时候可能需要数值型地址,或者防止IP地址伪装……所以我对整个过程进行了包装,方便日后使用。
/** * 获取客户端IP地址 * @param int $type [IP地址类型] * @param bool $strict [是否以严格模式获取] * @return mixed [客户端IP地址] */ function client_ip($type = 0, $strict = false) { $ip = null; // 0 返回字段型地址(127.0.0.1) // 1 返回长整形地址(2130706433) $type = $type ? 1 : 0; if ($strict) { /* 防止IP地址伪装的严格模式 */ if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown', $arr); if (false !== $pos) { unset($arr[$pos]); } $ip = trim(current($arr)); } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } } else if (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } /* IP地址合法性验证 */ $long = sprintf("%u", ip2long($ip)); $ip = $long ? [$ip, $long] : ['0.0.0.0', 0]; return $ip[$type]; }
提示:本地访问 localhost 的时候函数返回 0.0.0.0。
====================cURL函数=====================
PHP 的 libcurl 库可以让服务器通过各类协议进行连接和通讯,通过cURL我们可以向服务接口发送数据获取响应。
cURL中HTTP请求包含初始化、设置选项、执行响应、释放句柄四个操作,这里我对其进行了封装。
/** * cURL请求函数 * @param string $url [请求的URL地址] * @param array $params [请求的参数] * @param bool $post [是否采用POST形式] * @return mixed [请求结果|失败返回FALSE] */ function curl_tool($url, $params = [], $post = false) { /* 创建cURL句柄 */ $ch = curl_init(); /* 设置URL连接参数 */ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);// 设置尝试连接等待时间 curl_setopt($ch, CURLOPT_TIMEOUT, 60);// 设置cURL函数执行的最长时间 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// 将执行结果以字符串返回 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);// 根据响应头信息进行重定向 /* POST与GET请求 */ $params = http_build_query($params);// 将请求参数转换为字符串形式 if ($post) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); } else { $url = $url . ($params ? '?' : '') . $params; } curl_setopt($ch, CURLOPT_URL, $url); /* 抓取URL并关闭资源 */ $response = curl_exec($ch); // if ($response === false) echo curl_error($ch); curl_close($ch); return $response; }
提示:去掉 echo curl_error($ch) 的注释可以查看函数返回 FALSE 的原因。
====================查询IP位置=====================
解决了 获取IP地址 和 发送HTTP请求 的问题,就可以通过 http://apis.juhe.cn/ip/ip2addr 接口查询IP地址的地理位置信息了。
$url = "http://apis.juhe.cn/ip/ip2addr"; // 接口地址 // $appkey 填写您在聚合数据申请的 APPKEY $appkey = '80701ec21437ca36ca466af27bb8e8d3'; // 调试APPKEY $params = array( "ip" => client_ip(),//需要查询的IP地址或域名 "key" => $appkey,//应用APPKEY(应用详细页查询) "dtype" => "json",//返回数据的格式,xml或json,默认json ); // 获取响应内容,失败时为FALSE $content = curl_tool($url, $params); // 将JSON转换为数组打印输出 $result = json_decode($content, true); print_r($result);
通过外网访问的结果:
Array ( [resultcode] => 200 [reason] => Return Successd! [result] => Array ( [area] => 北京市 [location] => 电信 ) [error_code] => 0 )
注意:如果直接通过 localhost 访问,API 会提示 Wrong IP address! 错误。