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! 错误。

 

posted @ 2017-01-12 18:26  woider  阅读(2846)  评论(0编辑  收藏  举报