Emlog显示评论者IP地理信息的三种方法-三种方法-重要的说两遍

2015-7-19 / 2 评论 emlog / Mrxn

本文共计 6755 字,感谢您的耐心浏览与评论.

emlog系统存储了评论人的IP地址,有的时候,需要显示该IP的真实地理地址,可以通过以下两种方法获得。

一、本地获得IP地理地址。通过本地查找本地IP数据库(纯真版)来获得,IP数据库可以到http://www.cz88.net/下载安装后,在安装目录里把qqwry.dat文件提取出来,放到emlog根目录即可。 (保证与index.php同在一个目录中)

在module.php中添加以下代码:


<?php
 //获取IP地理地址
$data = '254.254.254.254';
 class IpLocation {
      var $fp;
      var $firstip;
      var $lastip;
      var $totalip;
          
      function getlong() {
         $result = unpack('Vlong', fread($this->fp, 4));
         return $result['long'];
      }

     function getlong3() {
         $result = unpack('Vlong', fread($this->fp, 3).chr(0));
         return $result['long'];
      }

      function packip($ip) {
         return pack('N', intval(ip2long($ip)));
      }
          
      function getstring($data = "") {
         $char = fread($this->fp, 1);
         while (ord($char) > 0) {
             $data .= $char;
             $char = fread($this->fp, 1);
         }
         return $data;
      }
          
      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;
         }
          
      function getlocation($ip) {
         
         if (!$this->fp) return null;
         $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 ($location['country'] == " CZNET") { 
             $location['country'] = "未知";
         }
         if ($location['area'] == " CZNET") {
             $location['area'] = "";
         }
         return $location;
      }
          
      function IpLocation($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, '_IpLocation'));
         }
      }
          
      function _IpLocation() {
         if ($this->fp) {
             fclose($this->fp);
         }
         $this->fp = 0;
      }
 }

 function getaddress($myip){
 $ipOrDomain=$myip;
 $iplocation = new IpLocation();
 $location = $iplocation->getlocation($ipOrDomain);
 $address=mb_convert_encoding($location['country'].$location['area'], "utf-8", "gbk");
 return $address;
 }
 ?>
然后在需要显示的地方插入:



<?php echo getaddress($comment['ip']);?>



即可。

 

二、通过远程网站相关接口实现。

在module.php中添加以下代码:


 <?php
 //blog:获取IP地址所在地,提取新浪IP接口
function getaddress($ip)
 {
 //调用sina查询接口
$str = file_get_contents("http://counter.sina.com.cn/ip?ip=".$ip);
 //转换字符集
$str = mb_convert_encoding($str,"UTF-8","GBK");  
 //匹配结果
preg_match_all('/[\x{4e00}-\x{9fa5}]+/u',$str,$get);
 //将数组转换成字符串
$add = implode('-',$get[0]);
 //返回结果
return $add;
 }
 ?>
然后在需要显示的地方插入:



<?php echo getaddress($comment['ip']);?>

即可。

图片显示方式:

<a title= <?php echo getaddress($comment['ip']);?>>&nbsp;<img src="./content/templates/default/images/ip.png" rel="external nofollow" ></a>
其中ip.png这个图标会显示在评论人的后面,图片自找,鼠标放上去会显示地理地址。
另一种方法显示IP:


1.首先在当前模板的module.php最后添加如下代码:


    <?php
    function convertip($ip) {   
        $dat_path = EMLOG_ROOT.'/content/templates/你的模板文件/QQWry.Dat'; //*数据库路径*//  
        if(!$fd = @fopen($dat_path, 'rb')){   
            return 'IP数据库文件不存在或者禁止访问或者已经被删除!';   
        }   
        $ip = explode('.', $ip);   
        $ipNum = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3];   
        $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;   
        while($ip1num>$ipNum || $ip2num<$ipNum) {   
            $Middle= intval(($EndNum + $BeginNum) / 2);   
            fseek($fd, $ipbegin + 7 * $Middle);   
            $ipData1 = fread($fd, 4);   
            if(strlen($ipData1) < 4) {   
                fclose($fd);   
                return '系统出错!';   
            }   
            $ip1num = implode('', unpack('L', $ipData1));   
            if($ip1num < 0) $ip1num += pow(2, 32);   
            if($ip1num > $ipNum) {   
                $EndNum = $Middle;   
                continue;   
            }   
            $DataSeek = fread($fd, 3);   
            if(strlen($DataSeek) < 3) {   
                fclose($fd);   
                return '系统出错!';   
            }   
            $DataSeek = implode('', unpack('L', $DataSeek.chr(0)));   
            fseek($fd, $DataSeek);   
            $ipData2 = fread($fd, 4);   
            if(strlen($ipData2) < 4) {   
                fclose($fd);   
                return '系统出错!';   
            }   
            $ip2num = implode('', unpack('L', $ipData2));   
            if($ip2num < 0) $ip2num += pow(2, 32);   
            if($ip2num < $ipNum) {   
                if($Middle == $BeginNum) {   
                    fclose($fd);   
                    return '未知';   
                }   
                $BeginNum = $Middle;   
            }   
        }   
        $ipFlag = fread($fd, 1);   
        if($ipFlag == chr(1)) {   
            $ipSeek = fread($fd, 3);   
            if(strlen($ipSeek) < 3) {   
                fclose($fd);   
                return '系统出错!';   
            }   
            $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 '系统出错!';   
            }   
            $ipFlag = fread($fd, 1);   
            if($ipFlag == chr(2)) {   
                $AddrSeek2 = fread($fd, 3);   
                if(strlen($AddrSeek2) < 3) {   
                    fclose($fd);   
                    return '系统出错!';   
                }   
                $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 '系统出错!';   
                }   
                $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 = '未知';   
        }   
        $ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr);    
        if( $ipaddr != '  ' )   
            return $ipaddr;   
        else  
            $ipaddr = '评论者来自火星,无法或者其所在地!';   
            return $ipaddr;   
    }
    ?>

然后再在评论中添加要你要显示位置。原作者未给出图片提示的代码。

纯文字显示代码:

<?php echo convertip($comment['ip']); ?>
图片title显示代码:



<img src="<?php echo BLOG_URL; ?>XXX/ip.png" rel="external nofollow"  alt="<?php echo convertip($comment['ip']); ?>" title="<?php echo convertip($comment['ip']); ?>"   width="16" height="16" class="useragent" data-bd-imgshare-binded="1">

上面代码中的XXX/ip.png是图片路径

其中使用到的纯真数据库以及图片自己下载,本博主暂不提供。


标签: 编程 代码 emlog IP代理 显示ip

转载:转载请注明原文链接 - Emlog显示评论者IP地理信息的三种方法-三种方法-重要的说两遍


2条回应:“Emlog显示评论者IP地理信息的三种方法-三种方法-重要的说两遍”


发表评论

{view_code_no}