全国服务热线:4008-888-888

公司新闻

PHP运用童真IP数据信息库在当地完成IP详细地址信

提议当地IP详细地址数据信息库,请到这一网站免费下载一个童真IP数据信息库,安裝进行后,到安裝文件目录里把QQWry.dat文档取下来,这一便是大家要想的IP数据信息库了,放进你要要文件目录下。 反面这一IP详细地址查寻解决的类  
 ?php
 
 * IP 自然地理部位查寻类
 */
class Helper_IpLocation
    /**
     * QQWry.Dat文档指针
     *
     * @var resource
     */
    private $fp;
    /**
     * 第一条IP纪录的偏位详细地址
     *
     * @var int
     */
    private $firstip;
    /**
     * 最终一条IP纪录的偏位详细地址
     *
     * @var int
     */
    private $lastip;
    /**
     * IP纪录的总总数(不包括版本号信息内容纪录)
     *
     * @var int
     */
    private $totalip;
 
    /**
     * 结构涵数,开启 QQWry.Dat 文档并原始化类中的信息内容
     *
     * @param string $filename
     */
    public function __construct($filename = 'qqwry.dat')
    {
        $this- fp = 0;
        if (($this- fp = fopen($filename, 'rb')) !== false) {
            $this- firstip = $this- getlong();
            $this- lastip = $this- getlong();
            $this- totalip = ($this- lastip - $this- firstip) / 7;
            //申请注册析构涵数,使其在程序运行完毕时实行
            register_shutdown_function(array(
                $this,
                '__destruct'
            ));
        }
    }
 
    /**
     * 析构涵数,用以在网页页面实行完毕后全自动关掉开启的文档。
     *
     */
    public function __destruct()
    {
        if ($this- fp) {
            fclose($this- 
        }
        $this- fp = 0;
    }
 
    /**
     * 回到载入的长整型数
     *
     * @access private
     * @return int
     */
    private function getlong()
    {
        //将载入的little-endian编号的4个字节数转换为长整型数
        $result = unpack('Vlong', fread($this- fp, 4));
        return $result['long'];
    }
 
    /**
     * 回到载入的3个字节数的长整型数
     *
     * @access private
     * @return int
     */
    private function getlong3()
    {
        //将载入的little-endian编号的3个字节数转换为长整型数
        $result = unpack('Vlong', fread($this- fp, 3) . chr(0));
        return $result['long'];
    }
 
    /**
     * 回到缩小后可开展较为的IP详细地址
     *
     * @access private
     * @param string $ip
     * @return string
     */
    private function packip($ip)
    {
        // 将IP详细地址转换为长整型数,假如在PHP5中,IP详细地址不正确,则回到False,
        // al将Flase转换为整数金额-1,以后缩小成big-endian编号的标识符串
        return pack('N', intval(ip2long($ip)));
    }
 
    /**
     * 回到载入的标识符串
     *
     * @access private
     * @param string $data
     * @return string
     */
    private function getstring($data = "")
    {
        $char = fread($this- fp, 1);
        while (ord($char) 0) { // 标识符串依照C文件格式储存,以完毕
            $data .= $char; // 将载入的标识符联接到给定标识符串以后
            $char = fread($this- fp, 1);
        }
        return iconv('gbk', 'utf-8', $data);
    }
 
    /**
     * 回到地域信息内容
     *
     * @access private
     * @return string
     */
    private function getarea()
    {
        $byte = fread($this- fp, 1); // 标示字节数
        switch (ord($byte)) {
            case 0: // 沒有地区信息内容
                $area = "";
                break;
            case 1:
            case 2: // 标示字节数为1或2,表明地区信息内容被跳转
                fseek($this- fp, $this- getlong3());
                $area = $this- getstring();
                break;
            default: // 不然,表明地区信息内容沒有被跳转
                $area = $this- getstring($byte);
                break;
        }
        return $area;
    }
 
    /**
     * 依据所给 IP 详细地址或网站域名回到所属地域信息内容
     *
     * @access public
     * @param string $ip
     * @return array
     */
    public function getlocation($ip)
    {
        if (!$this- fp)
            return null; // 假如数据信息文档沒有被恰当开启,则立即回到空
        $location['ip'] = gethostbyname($ip); // 将键入的网站域名转换为IP详细地址
        $ip = $this- packip($location['ip']); // 将键入的IP详细地址转换为相比较的IP详细地址
        // 不符合法的IP详细地址会被转换为255.255.255.255
        // 对分检索
        $l = 0; // 检索的下面界
        $u = $this- totalip; // 检索的上面界
        $findip = $this- lastip; // 假如沒有寻找就回到最终一条IP纪录(QQWry.Dat的版本号信息内容)
        while ($l = $u) { // 当上面界低于下面界时,搜索不成功
            $i = floor(($l + $u) / 2); // 测算类似正中间纪录
            fseek($this- fp, $this- firstip + $i * 7);
            $beginip = strrev(fread($this- fp, 4)); // 获得正中间纪录的刚开始IP详细地址
            // strrev涵数在这里里的功效是将little-endian的缩小IP详细地址转换为big-endian的文件格式
            // 便于用以较为,后边同样。
            if ($ip $beginip) { // 客户的IP低于正中间纪录的刚开始IP详细地址时
                $u = $i - 1; // 将检索的上面界改动为正中间纪录减一
            } else {
                fseek($this- fp, $this- getlong3());
                $endip = strrev(fread($this- fp, 4)); // 获得正中间纪录的完毕IP详细地址
                if ($ip $endip) { // 客户的IP超过正中间纪录的完毕IP详细地址时
                    $l = $i + 1; // 将检索的下面界改动为正中间纪录加一
                } else { // 客户的IP先在间纪录的IP范畴内时
                    $findip = $this- firstip + $i * 7;
                    break; // 则表明寻找結果,撤出循环系统
                }
            }
        }
        //获得搜索到的IP自然地理部位信息内容
        fseek($this- fp, $findip);
        $location['beginip'] = long2ip($this- getlong()); // 客户IP所属范畴的刚开始详细地址
        $offset = $this- getlong3();
        fseek($this- fp, $offset);
        $location['endip'] = long2ip($this- getlong()); // 客户IP所属范畴的完毕详细地址
        $byte = fread($this- fp, 1); // 标示字节数
        switch (ord($byte)) {
            case 1: // 标示字节数为1,表明我国和地区信息内容都被同时跳转
                $countryOffset = $this- getlong3(); // 跳转详细地址
                fseek($this- fp, $countryOffset);
                $byte = fread($this- fp, 1); // 标示字节数
                switch (ord($byte)) {
                    case 2: // 标示字节数为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: // 标示字节数为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 ($location['country'] == " CZ88.NET") { // CZ88.NET表明沒有合理信息内容
            $location['country'] = "不明";
        }
        if ($location['area'] == " CZ88.NET") {
            $location['area'] = "";
        }
        return $location;
    }
启用方法: ?php
 
include 'IpLocation.php';
 
echo " pre  
$ip = "180.76.6.130";  
$iplocation = new IpLocation();  
$location = $iplocation- getlocation($ip);  
print_r($location);  
 



在线客服

关闭

客户服务热线
4008-888-888


点击这里给我发消息 在线客服

点击这里给我发消息 在线客服