1. 程式人生 > >PHP 通過ip獲取國家及地址方法集合

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查詢

1.laravel 安裝geo   

執行 :composer require geoip2/geoip2:~2.0(需要給vendor以及composer.lock許可權)

新增成功後,composer.json和comoser.lock會新增對應的配置檔案。

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