PHP 通过ip获取国家及地址方法集合

一、通过http请求淘宝和新浪的接口进行在线查询

优点:调用简单方便代码量少   缺点:在无网络的情况下无法查询。

print_r(get_area('223.67.235.28'));
function get_area($ip = ''){
    if($ip == ''){
        $ip = GetIp();
    }
    $url = "http://ip.taobao.com/service/getIpInfo.php?ip={$ip}";//淘宝
    //$res = @file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=' . $ip);//新浪
    $ret = https_request($url);
    $arr = json_decode($ret,true);
    return $arr;
}

二、通过纯真ip库进行查询

优点:可以查询城市的具体信息  缺点:无法直接定位到国家

1.下载qqwry.dat 库进行查询。

2.调用代码

function searchIpMessage($ip)
{
    $ip = long2ip($ip);
    $ip1num = 0;
    $ip2num = 0;
    $ipAddr1 = "";
    $ipAddr2 = "";
    $dat_path = '../qqwry.dat';
    if (!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {
        return 'IP Address Error';
    }
    if (!$fd = @fopen($dat_path, 'rb')) {
        return 'IP date file not exists or access denied';
    }
    $ip = explode('.', $ip);
    $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];
    //获取IP数据索引开始和结束位置 ↓
    $DataBegin = fread($fd, 4);
    $DataEnd = fread($fd, 4);
    $ipbegin = implode('', unpack('L', $DataBegin));
    if ($ipbegin < 0) $ipbegin += pow(2, 32);
    $ipend = implode('', unpack('L', $DataEnd));
    if ($ipend < 0) $ipend += pow(2, 32);
    $ipAllNum = ($ipend - $ipbegin) / 7 + 1;
    $BeginNum = 0;
    $EndNum = $ipAllNum;
    //使用二分查找法从索引记录中搜索匹配的IP记录
    while ($ip1num > $ipNum || $ip2num < $ipNum) {
        $Middle = intval(($EndNum + $BeginNum) / 2);
        //偏移指针到索引位置读取4个字节
        fseek($fd, $ipbegin + 7 * $Middle);
        $ipData1 = fread($fd, 4);
        if (strlen($ipData1) < 4) {
            fclose($fd);
            return 'System Error';
        }
        //提取出来的数据转换成长整形,如果数据是负数则加上2的32次幂
        $ip1num = implode('', unpack('L', $ipData1));
        if ($ip1num < 0) $ip1num += pow(2, 32);
        //提取的长整型数大于我们IP地址则修改结束位置进行下一次循环
        if ($ip1num > $ipNum) {
            $EndNum = $Middle;
            continue;
        }
        //取完上一个索引后取下一个索引
        $DataSeek = fread($fd, 3);
        if (strlen($DataSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $DataSeek = implode('', unpack('L', $DataSeek . chr(0)));
        fseek($fd, $DataSeek);
        $ipData2 = fread($fd, 4);
        if (strlen($ipData2) < 4) {
            fclose($fd);
            return 'System Error';
        }
        $ip2num = implode('', unpack('L', $ipData2));
        if ($ip2num < 0) $ip2num += pow(2, 32);
        if ($ip2num < $ipNum) {
            if ($Middle == $BeginNum) {
                fclose($fd);
                return 'Unknown';
            }
            $BeginNum = $Middle;
        }
    }
    $ipFlag = fread($fd, 1);
    if ($ipFlag == chr(1)) {
        $ipSeek = fread($fd, 3);
        if (strlen($ipSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipSeek = implode('', unpack('L', $ipSeek . chr(0)));
        fseek($fd, $ipSeek);
        $ipFlag = fread($fd, 1);
    }
    if ($ipFlag == chr(2)) {
        $AddrSeek = fread($fd, 3);
        if (strlen($AddrSeek) < 3) {
            fclose($fd);
            return 'System Error';
        }
        $ipFlag = fread($fd, 1);
        if ($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if (strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while (($char = fread($fd, 1)) != chr(0))
            $ipAddr2 .= $char;
        $AddrSeek = implode('', unpack('L', $AddrSeek . chr(0)));
        fseek($fd, $AddrSeek);
        while (($char = fread($fd, 1)) != chr(0))
            $ipAddr1 .= $char;
    } else {
        fseek($fd, -1, SEEK_CUR);
        while (($char = fread($fd, 1)) != chr(0))
            $ipAddr1 .= $char;
        $ipFlag = fread($fd, 1);
        if ($ipFlag == chr(2)) {
            $AddrSeek2 = fread($fd, 3);
            if (strlen($AddrSeek2) < 3) {
                fclose($fd);
                return 'System Error';
            }
            $AddrSeek2 = implode('', unpack('L', $AddrSeek2 . chr(0)));
            fseek($fd, $AddrSeek2);
        } else {
            fseek($fd, -1, SEEK_CUR);
        }
        while (($char = fread($fd, 1)) != chr(0)) {
            $ipAddr2 .= $char;
        }
    }
    fclose($fd);
    if (preg_match('/http/i', $ipAddr2)) {
        $ipAddr2 = '';
    }
    $ipaddr = "$ipAddr1";
    $ipaddr = preg_replace('/CZ88.NET/is', '', $ipaddr);
    $ipaddr = preg_replace('/^s*/is', '', $ipaddr);
    $ipaddr = preg_replace('/s*$/is', '', $ipaddr);
    if (preg_match('/http/i', $ipaddr) || $ipaddr == '') {
        $ipaddr = 'Unknown';
    }
    $str = iconv("gb2312", "utf-8//IGNORE", $ipaddr); //这边纯真IP数据库获取到的gb2312格式的文字,要先转成UTF8
    return $str;
}

三、通过Geoip查询

原文链接:https://sjolzy.cn/GeoIP-PHP-version-use.html

1.laravel 安装geo   

执行 :composer require geoip2/geoip2:~2.0(需要给vendor以及composer.lock权限)

PHP 通过ip获取国家及地址方法集合

添加成功后,composer.json和comoser.lock会新增对应的配置文件。

2.下载免费geoip库 //sjolzy.cn/php/GeoIP/bak/GeoIP.dat.gz 。解压得到GeoIP.dat。

3.下载对应的php文件geoip.inc,保存为 geoip.inc.php

2.文件新增代码

use GeoIp2\Database\Reader;
public function selectIp(){
    include("../geoip.inc.php");
    // 打开数据文件
    $gi = geoip_open("../GeoIP.dat",GEOIP_STANDARD);
    // 获取国家代码
    $ip = long2ip(2000436901);
    var_dump($ip);
    $country_code = geoip_country_code_by_addr($gi,$ip);
    // 获取国家名称
    $country_name = geoip_country_name_by_addr($gi,$ip);
    var_dump($country_code);
    var_dump($country_name);
    exit;
    // 关闭文件
    geoip_close($gi);
}

四、把GeoIP安装成php扩展

把 GeoIP 安装成 PHP 扩展
yum install GeoIP GeoIP-data GeoIP-devel

 

下载 GeoIP 数据库
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gzip -d GeoLiteCity.dat.gz
mv GeoLiteCity.dat /var/lib/GeoIP/GeoIPCity.dat

 

下载 GeoIP 的 PECL 扩展
下载地址 http://pecl.php.net/package/geoip
wget -c http://pecl.php.net/get/geoip-1.0.7.tgz
tar -zxvf geoip-1.0.7.tgz

 

安 装 GeoIP 的 PECL 扩展
cd geoip-1.0.7
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-geoip
make
make install

 

在 php.ini 里加上
extension=geoip.so

接着重启一下 php 就行了
现在,你可以使用 php 手册里的 GeoIP 部份函数了
http://cn.php.net/manual/en/book.geoip.php

原文地址://sjolzy.cn/post-612.html