如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留链接信息。

伴随着中国互联网的发展史,从当年的显IPQQ开始,大名鼎鼎的纯真数据库qqwry,就伴随着中国人的网络史而存在。当年的木子QQ,珊瑚虫QQ,后来的DZ论坛等等,都有qqwry的存在,这个数据库的名称是怎么来的,无从得知。是谁维护的也不知晓。不过应该是做站必备利器。

最近,苏南大叔想做个ip相关的判断,所以就又想起了它。百度了一番,发现它居然有个官方站,http://www.cz88.net/ 。界面呢,以最新的网络观来说,略low。似乎有些苍白的感觉。不管如何,界面上面有个明显的下载按钮。点击之后,令我意外的是,居然是个exe。说好的dat文件呢?好吧,可能在exe里面包含着呢。不情愿的安装了exe后,果然在目录下面发现了期待的qqwry.dat。看着exe的界面上有个“升级”的按钮的份上,就保留了exe。嘿嘿,没准哪天还真心升级下呢。

纯真IP库最新版,PHP解析 - qqwry
纯真IP库最新版,PHP解析(图1-1)

然后百度个PHP解析的代码吧,发现了个大名鼎鼎的dz的,试了一下。貌似有问题,似乎其中的正则部分,有问题。而苏南大叔最不喜欢正则了,所以直接过了。然后又百度到了大名鼎鼎的thinkphp的作者liu21st的作品。马上膜拜一下下。下载回来试试,果然赞。

不过可能在转载的过程中,也缺失了个函数,马上补上。话说,php这点上就确实不如hack语言好,php下丢了个函数,如果不运行到对应地方,永远都不会提示有错误。而hack语言,作为PHP的小表弟,是一门静态类型的语言。这种小错误根本不会遗留到线上的。大家如果有疑问,可以看看 http://hacklang.org.cn 的相关介绍。最后还是要喊句口号,“PHP是世界上最好的语言”~

下面贴出我修改过的liusir的ip代码解析,稍稍修改了下逻辑,能清楚的标识出国家是中国的情况,并且添加上了丢失的函数。大家喜欢就拿走好了。我改编的liusir的,liusir貌似改编的其他人的... @liu21st,我顺手又把你的顶部注释删除了,sorry。

class IpLocation {
    private $fp;
    private $firstip;
    private $lastip;
    private $totalip;
    public function __construct($filename = "data/qqwry.dat") {
        $this->fp = 0;
        if (($this->fp = fopen(dirname(__FILE__) . '/' . $filename, 'rb')) !== false) {
            $this->firstip = $this->getlong();
            $this->lastip = $this->getlong();
            $this->totalip = ($this->lastip - $this->firstip) / 7;
        }
    }
    private function getlong() {
        //将读取的little-endian编码的4个字节转化为长整型数
        $result = unpack('Vlong', fread($this->fp, 4));
        return $result['long'];
    }
    private function getlong3() {
        $result = unpack('Vlong', fread($this->fp, 3) . chr(0));
        return $result['long'];
    }
    private function packip($ip) {
        return pack('N', intval(ip2long($ip)));
    }
    private function getstring($data = "") {
        $char = fread($this->fp, 1);
        while (ord($char) > 0) {
            $data .= $char;
            $char = fread($this->fp, 1);
        }
        return $data;
    }
    private function getarea() {
        $byte = fread($this->fp, 1);
        switch (ord($byte)) {
            case 0:
                $area = "";
                break;
            case 1:
            case 2:
                fseek($this->fp, $this->getlong3());
                $area = $this->getstring();
                break;
            default:
                $area = $this->getstring($byte);
                break;
        }
        return $area;
    }
    private $provinces = array("黑龙江省", "辽宁省", "吉林省", "河北省", "河南省", "湖北省", "湖南省", "山东省", "山西省", "陕西省","安徽省", "浙江省", "江苏省", "福建省", "广东省", "海南省", "四川省", "云南省", "贵州省", "青海省", "甘肃省","江西省", "台湾省", "内蒙古", "宁夏", "新疆", "西藏", "广西", "北京市", "上海市", "天津市", "重庆市", "香港", "澳门");
    public function getlocation($ip = '') {
        if (!$this->fp)
            return null;
        if (empty($ip))
            $ip = get_client_ip();
        $location['ip'] = gethostbyname($ip);
        $ip = $this->packip($location['ip']);
        $l = 0;
        $u = $this->totalip;
        $findip = $this->lastip;
        while ($l <= $u) {
            $i = floor(($l + $u) / 2);
            fseek($this->fp, $this->firstip + $i * 7);
            $beginip = strrev(fread($this->fp, 4));
            if ($ip < $beginip) {
                $u = $i - 1;
            } else {
                fseek($this->fp, $this->getlong3());
                $endip = strrev(fread($this->fp, 4));
                if ($ip > $endip) {
                    $l = $i + 1;
                } else {
                    $findip = $this->firstip + $i * 7;
                    break;
                }
            }
        }
        fseek($this->fp, $findip);
        $location['beginip'] = long2ip($this->getlong());
        $offset = $this->getlong3();
        fseek($this->fp, $offset);
        $location['endip'] = long2ip($this->getlong());
        $byte = fread($this->fp, 1);
        switch (ord($byte)) {
            case 1:
                $countryOffset = $this->getlong3();
                fseek($this->fp, $countryOffset);
                $byte = fread($this->fp, 1);
                switch (ord($byte)) {
                    case 2:
                        fseek($this->fp, $this->getlong3());
                        $location['country'] = $this->getstring();
                        fseek($this->fp, $countryOffset + 4);
                        $location['area'] = $this->getarea();
                        break;
                    default:
                        $location['country'] = $this->getstring($byte);
                        $location['area'] = $this->getarea();
                        break;
                }
                break;
            case 2:
                fseek($this->fp, $this->getlong3());
                $location['country'] = $this->getstring();
                fseek($this->fp, $offset + 8);
                $location['area'] = $this->getarea();
                break;
            default:
                $location['country'] = $this->getstring($byte);
                $location['area'] = $this->getarea();
                break;
        }
        if (trim($location['country']) == 'CZ88.NET') {
            $location['country'] = '未知';
        }
        if (trim($location['area']) == 'CZ88.NET') {
            $location['area'] = '';
        }
        $location['country'] = @iconv('gbk', 'utf-8', $location['country']);
        $location['area'] = @iconv('gbk', 'utf-8', $location['area']);
        foreach ($this->provinces as $v) {
            if (strpos($location['country'], $v) === 0) {
                $location['province'] = $v;
                $location['city'] = str_replace($v, '', $location['country']);
                break;
            }
        }
        if (empty($location['province']))
            $location['province'] = $location['country'];
        if (empty($location['city']))
            $location['city'] = $location['country'];
        //sunan moify
        if (in_array($location['province'], $this->provinces)) {
            $location['country'] = "中国";
        }
        return $location;
    }
    public function __destruct() {
        if ($this->fp) {
            fclose($this->fp);
        }
        $this->fp = 0;
    }
}
function get_client_ip() {
    if (getenv('HTTP_CLIENT_IP')) {
        $onlineip = getenv('HTTP_CLIENT_IP');
    } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
        $onlineip = getenv('HTTP_X_FORWARDED_FOR');
    } elseif (getenv('REMOTE_ADDR')) {
        $onlineip = getenv('REMOTE_ADDR');
    } else {
        $onlineip = $HTTP_SERVER_VARS['REMOTE_ADDR'];
    }
    return $onlineip;
}

header("Content-type: text/html; charset=utf-8");
$new = new IpLocation();
$ip = $new->getlocation();
//$ip = $new->getlocation("114.249.231.28");
print_r($ip);

 【源码】代码片段及相关软件点此获取

 【php】秘籍文章入口,仅传授于有缘之人   php    IP

本站的忠实读者小伙伴,正在阅读下面这些文章:

欢迎转载传播本篇原创文章,转载请保留链接及作者信息。
欢迎指正文字或逻辑错误,将会择优在文末列出您的信息。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
未经许可,规模化镜像抄袭本站内容的行为,将会根据有关法律法规进行维权。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

苏南大叔需要你的支持

感谢您的打赏,让我更有动力,将更多精彩教程文章,呈现给大家!谢谢!