php IP获取城市API(纯真IP数据库)

发布时间:2020-12-24编辑:脚本学堂
本文介绍下,使用纯真IP数据库,根据IP获取城市的API代码一例,有兴趣的朋友可以参考研究下。

本节主要内容:
根据IP地址获取城市名称的php代码。
用到了纯真ip数据库实现。

本例php代码,透过纯真IP数据库的支持,可以精确地定位城市位置。
支持多种查询方式形如:本机IP、自定义IP、自定义域名三种方式。
http://domain/ip 直接查询本机IP所在城市位置
http://domain/ip/?q=xxx.xxx.xxx.xxx 获取自定义IP的城市位置
http://domain/ip/?q=baidu.com 获取域名所在的城市位置

例子:
 

复制代码 代码示例:
<?php
/**
* 根据IP地址取得城市名称 纯真IP数据库
* edit: www.jb200.com
*/
  function convertip($ip) {
    //IP数据文件路径
    $dat_path = 'QQWry.Dat';
 
    //检查IP地址
    if(!filter_var($ip, FILTER_VALIDATE_IP)) {
        return 'IP Address Error';
    }
    //打开IP数据文件
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP date file not exists or access denied';
    }
 
    //分解IP进行运算,得出整形数
    $ipNum = ip2long($ip);
 
    //获取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 $ipAddr2";
    $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';
    }
 
    return $ipaddr;
}
header("Content-type: text/html; charset=utf-8");
$ip =  $_SERVER['HTTP_X_FORWARDED_FOR'];
if(isset($_GET['q'])){
    $ip = $_GET['q'];
    if(filter_var("http://".$ip,FILTER_VALIDATE_URL,FILTER_FLAG_HOST_requireD)){
        $ip = gethostbyname($ip);
    }
}
echo "$ip,".mb_convert_encoding(convertip($ip),"utf-8","gb2312");
 
?>