php: 根据ip地址得到所属的省市

一,代码:

说明:原代码来自于网络,我把它做了封装,去掉了其中无响应的接口,对有些地址有变化的接口做了更新,
         确保到目前为止所调用的接口都可用,
        不再直接返回json,而是返回数组

<?php
/*
根据ip得到所属的省市信息
*/
class CityByIp
{

    // 中国34个省级行政区域
    private $provinces = array(
        "北京",
        "天津",
        "河北",
        "山西",
        "内蒙古",
        "辽宁",
        "吉林",
        "黑龙江",
        "上海",
        "江苏",
        "浙江",
        "安徽",
        "福建",
        "江西",
        "山东",
        "河南",
        "湖北",
        "湖南",
        "广东",
        "广西",
        "海南",
        "重庆",
        "四川",
        "贵州",
        "云南",
        "西藏",
        "陕西",
        "甘肃",
        "青海",
        "宁夏",
        "新疆",
        "香港",
        "澳门",
        "台湾"
    );


    //构造
    public function __construct() {

    }


    //得到ip对应的省市
    function getCity($ip){

        if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
             return [
                 'code' => 201,
                 'msg' => 'ip地址错误'
            ];
        }

            // 请求接口
        $methods = [
            'getCityByCSDN',
            'getCityByIPChaxun',
            'getCityByVvhan',
            'getCityByRunoob'
        ];

        foreach ($methods as $method) {
            $response = $this->$method($ip);
            //echo $method.":\n";
            //var_dump($response);
            if ($response['code'] === 200) {
                // 如果请求成功,输出请求结果并停止循环
                //echo $method($ip);
                //break;
                return $response;
            }
        }


        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        if (!isset($response) || $response['code'] !== 200) {

            $ipinfo = array(
            'code' => 201,
            'msg' => '请求失败~'
           );
            return $ipinfo;
        //echo json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        //exit;
        }
    }


    //检查ip是否合法
    function checkIpValid($ip) {
            // 验证ipv4地址合法性
       if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            return false;
        } else {
            return true;
        }
    }

    // HTTP请求封装
    function cUrlGetIP($url) {

        // cUrl
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $header[] = 'user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36';
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        return curl_exec($ch);
        curl_close($ch);
    }

    // 接口2
    // https://searchplugin.csdn.net/api/v1/ip/get?ip={ip}
    function getCityByCSDN($ip) {

        $response = $this->cUrlGetIP('https://searchplugin.csdn.net/api/v1/ip/get?ip='.$ip);
        $code = json_decode($response,true)['code'];

        if($code == 200) {

            $str1 = json_decode($response,true)['data']['address'];

            // 国家
        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
            $country = explode(' ', $str1)[0];

            // 省份
            $province = explode(' ', $str1)[1];

            // 城市
            $city = explode(' ', $str1)[2];

            // 县区
            $district = '';

            // 判断是否获取成功
            if($country || $province || $city || $district) {

                // 拼接数组
                $ipinfo = array(
                    'code' => 200,
                    'msg' => '获取成功',
                    'ipinfo' => array(
                        'country' => $country,
                        'province' => $province,
                        'city' => $city,
                        'district' => $district,
                        'ip' => json_decode($response,true)['data']['ip']
                    )
                );
            }else {

                $ipinfo = array(
                    'code' => 201,
                    'msg' => '获取失败'
                );
            }
        }else {

            $ipinfo = array(
                'code' => 201,
                'msg' => '获取失败'
            );
        }

        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        return $ipinfo;
    }

    // 接口3
    // https://ipchaxun.com/{ip}/
    function getCityByIPChaxun($ip) {

        $response = $this->cUrlGetIP('https://ipchaxun.com/'.$ip.'/');
        $str1 = substr($response, strripos($response, "归属地") + 15);
        $str2 = substr($str1, 0, strrpos($str1, "运营商"));

        // 提取省份
        //global $provinces;
        foreach ($this->provinces as $province_) {
            if (strpos($str2, $province_) !== false) {
                $province = $province_;
                break;
            }
        }

        // 提取国家
        $str3 = substr($str2, 0, strrpos($str2, $province));
        $country = preg_replace('/[^\x{4e00}-\x{9fa5}]+/u', '', $str3);
        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);reg_replace('/[^\x{4e00}-\x{9fa5}]+/u', '', $str3);

        // 提取城市
        $str4 = substr($str2, strripos($str2, "nofollow") + 10);
        $city = substr($str4, 0, strrpos($str4, "</a>"));

        // 提取县区
        $str6 = substr($str2, strripos($str2, "</a>") + 4);
        $district = substr($str6, 0, strrpos($str6, "</span>"));

        // 判断是否获取成功
        if($country || $province || $city || $district) {

            // 拼接数组
            $ipinfo = array(
                'code' => 200,
                'msg' => '获取成功',
                'ipinfo' => array(
                    'country' => $country,
                    'province' => $province,
                    'city' => $city,
                    'district' => $district,
                    'ip' => $ip
                )
            );
        }else {

            $ipinfo = array(
                'code' => 201,
                'msg' => '获取失败'
            );
        }

        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        return $ipinfo;
    }

    // 接口4
    // https://api.vvhan.com/api/getIpInfo?ip={ip}
    // https://api.vvhan.com/api/ipInfo?ip=58.154.0.0
    function getCityByVvhan($ip) {

        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        $response = $this->cUrlGetIP('https://api.vvhan.com/api/ipInfo?ip='.$ip);
        $success = json_decode($response,true)['success'];

        if($success == true) {

            $str1 = json_decode($response,true)['info'];

            // 国家
            $country = $str1['country'];

            // 省份
            $province = $str1['prov'];

            // 城市
            $city = $str1['city'];

            // 县区
            $district = '';

            // 判断是否获取成功
            if($country || $province || $city || $district) {

                // 拼接数组
                $ipinfo = array(
                    'code' => 200,
                    'msg' => '获取成功',
                    'ipinfo' => array(
                        'country' => $country,
                        'province' => $province,
                        'city' => $city,
                        'district' => $district,
                        'ip' => $ip
                    )
                );
            }else {

                $ipinfo = array(
                    'code' => 201,
                    'msg' => '获取失败'
                );
            }
        }else {

            $ipinfo = array(
                'code' => 201,
                'msg' => '获取失败'
            );
        }

        //return json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        return $ipinfo;
    }

    // 接口5
    // https://c.runoob.com/wp-content/themes/toolrunoob2/option/ajax.php?type=checkIP&REMOTE_ADDR={ip}
    // https://www.jyshare.com/wp-content/themes/toolrunoob2/option/ajax.php?type=checkIP&REMOTE_ADDR=223.72.50.231
    function getCityByRunoob($ip) {

        $response = $this->cUrlGetIP('https://www.jyshare.com/wp-content/themes/toolrunoob2/option/ajax.php?type=checkIP&REMOTE_ADDR='.$ip);

        $flag = json_decode($response,true)['flag'];

        if($flag == true) {

            $str1 = json_decode($response,true)['data'];

            // 国家
            $country = $str1['country'];

            // 省份
            $province = $str1['regionName'];

            // 城市
            $city = $str1['city'];

            // 县区
            $district = '';

            // 判断是否获取成功
            if($country || $province || $city || $district) {

                // 拼接数组
                $ipinfo = array(
                    'code' => 200,
                    'msg' => '获取成功',
                    'ipinfo' => array(
                        'country' => $country,
                        'province' => $province,
                        'city' => $city,
                        'district' => $district,
                        'ip' => $ip
                    )
                );
            }else {

                $ipinfo = array(
                    'code' => 201,
                    'msg' => '获取失败'
                );
            }
        }else {

            $ipinfo = array(
                'code' => 201,
                'msg' => '获取失败'
            );
        }

        return $ipinfo;
    }
}






$city = new CityByIp();
$ip = '120.6.106.14';
$res = $city->getCity($ip);
var_dump($res);




?>

 

二,测试效果:

liuhongdi@lhdpc:/data/work/2024_08$ php CityByIp.php 
array(3) {
  ["code"]=>
  int(200)
  ["msg"]=>
  string(12) "获取成功"
  ["ipinfo"]=>
  array(5) {
    ["country"]=>
    string(6) "中国"
    ["province"]=>
    string(6) "河北"
    ["city"]=>
    string(9) "秦皇岛"
    ["district"]=>
    string(0) ""
    ["ip"]=>
    string(12) "120.6.106.14"
  }
}

 

posted @ 2024-08-14 10:58  刘宏缔的架构森林  阅读(426)  评论(0编辑  收藏  举报