php获取客户端ip地址及ip所在国家、省份、城市、县区

摘要

获取客户端ip地址,然后使用这个ip地址获取所在的国家、省份、城市,可以在网站中实现IP属地,发布地等功能。

本文的获取IP地址信息均采自网络上免费的IP查询网站,通过其API或者网页HTML解析出的ip地址信息。

代码

复制代码
<?php

    // 编码
    header('Content-type:application/json');
    
    $ip = $_GET['ip'];
    
    // 过滤空数据
    if(!$ip) {
        
        $ipinfo = array(
            'code' => 201,
            'msg' => '未传入ip地址'
        );
        echo json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    // 验证ipv4地址合法性
    if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        
        $ipinfo = array(
            'code' => 201,
            'msg' => '这不是一个正确的ip地址'
        );
        echo json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    // 请求接口
    $methods = [
        'getMethod_1',
        'getMethod_2',
        'getMethod_3',
        'getMethod_4',
        'getMethod_5'
    ];
    
    foreach ($methods as $method) {
        $response = json_decode($method($ip));
        if ($response->code === 200) {
            
            // 如果请求成功,输出请求结果并停止循环
            echo $method($ip);
            break;
        }
    }
    
    if (!isset($response) || $response->code !== 200) {
        
        $ipinfo = array(
            'code' => 201,
            'msg' => '请求失败~'
        );
        echo json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    // 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);
    }
    
    // 中国34个省级行政区域
    $provinces = array(
        "北京",
        "天津",
        "河北",
        "山西",
        "内蒙古",
        "辽宁",
        "吉林",
        "黑龙江",
        "上海",
        "江苏",
        "浙江",
        "安徽",
        "福建",
        "江西",
        "山东",
        "河南",
        "湖北",
        "湖南",
        "广东",
        "广西",
        "海南",
        "重庆",
        "四川",
        "贵州",
        "云南",
        "西藏",
        "陕西",
        "甘肃",
        "青海",
        "宁夏",
        "新疆",
        "香港",
        "澳门",
        "台湾"
    );
    
    // 接口1
    // http://ipshudi.com/{ip}.htm
    function getMethod_1($ip) {
        
        $response = file_get_contents('http://ipshudi.com/'.$ip.'.htm');
        $str1 = substr($response, strripos($response, "归属地"));
        $str2 = substr($str1, 0, strrpos($str1, "运营商"));
        $str3 = substr($str2, strripos($str2, "<span>") + 6);
        $str4 = substr($str3, 0, strripos($str3, "</span>") + 6);
        
        // 提取国家
        $country = substr($str4, 0, strpos($str4, ' '));
        
        // 提取省份
        $str5 = substr($str4, 0, strrpos($str4, " <a href"));
        $province = substr($str5, strpos($str5, ' ') + 1);
        
        // 提取城市
        preg_match('/>([^<]+)</', $str4, $matches);
        $city = $matches[1];
        
        // 提取县区
        $str6 = substr($str4, strripos($str4, "</a>"));
        $district = preg_replace('/[^\x{4e00}-\x{9fa5}]+/u', '', $str6);
        
        // 判断是否获取成功
        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);
    }
    
    // 接口2
    // https://searchplugin.csdn.net/api/v1/ip/get?ip={ip}
    function getMethod_2($ip) {
        
        $response = 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'];
            
            // 国家
            $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);
    }
    
    // 接口3
    // https://ipchaxun.com/{ip}/
    function getMethod_3($ip) {
        
        $response = cUrlGetIP('https://ipchaxun.com/'.$ip.'/');
        $str1 = substr($response, strripos($response, "归属地") + 15);
        $str2 = substr($str1, 0, strrpos($str1, "运营商"));
        
        // 提取省份
        global $provinces;
        foreach ($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);
        
        // 提取城市
        $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);
    }
    
    // 接口4
    // https://api.vvhan.com/api/getIpInfo?ip={ip}
    function getMethod_4($ip) {
        
        $response = cUrlGetIP('https://api.vvhan.com/api/getIpInfo?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);
    }
    
    // 接口5
    // https://c.runoob.com/wp-content/themes/toolrunoob2/option/ajax.php?type=checkIP&REMOTE_ADDR={ip}
    function getMethod_5($ip) {
        
        $response = cUrlGetIP('https://c.runoob.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 json_encode($ipinfo,JSON_UNESCAPED_UNICODE);
    }

?>

使用

https://域名/getipInfo.php?ip=需要查询的IP地址

一共有5个接口,接口失效会使用下一个接口,直到接口成功,最终输出数据格式如下:

复制代码
{"code":200,"msg":"获取成功","ipinfo":{"country":"中国","province":"广东省","city":"广州市","district":"番禺区","ip":"xx.xx.xxx.xx"}}

作者

TANKING

相关推荐
两个人的幸福10 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack12 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820712 天前
PHP 扩展——从入门到理解
php
鹏仔先生13 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下13 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
xingpanvip13 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
酉鬼女又兒14 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
dog25014 天前
不要再继续优化 TCP
网络协议·tcp/ip·php
Channing Lewis14 天前
PHP 解析 Excel 的那些坑:一次“行号错位”引发的数据丢失
开发语言·php·excel