聚合數據 提供了【查詢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! 錯誤。