请输入图片描述

记录今天在祭华的博客学习到的在Typecho博客中显示网站评论者UA以及根据IP地址转真实地址并显示的问题。
具体效果如本站评论列表显示。
实现过程如下:
一、显示网站评论者UA:
在主题模板的functions.php文件里添加以下代码。

/** 获取浏览器信息 */

function getBrowser($agent){

$outputer = false;
if (preg_match('/MSIE\s([^\s|;]+)/i', $agent, $regs)) {
    $outputer = 'IE浏览器';
} else if (preg_match('/FireFox\/([^\s]+)/i', $agent, $regs)) {
  $str1 = explode('Firefox/', $regs[0]);
$FireFox_vern = explode('.', $str1[1]);
    $outputer = '火狐浏览器 '. $FireFox_vern[0];
} else if (preg_match('/Maxthon([\d]*)\/([^\s]+)/i', $agent, $regs)) {
  $str1 = explode('Maxthon/', $agent);
$Maxthon_vern = explode('.', $str1[1]);
    $outputer = '傲游浏览器 '.$Maxthon_vern[0];
} else if (preg_match('#SE 2([a-zA-Z0-9.]+)#i', $agent, $regs)) {
    $outputer = '搜狗浏览器';
} else if (preg_match('#360([a-zA-Z0-9.]+)#i', $agent, $regs)) {
$outputer = '360浏览器';
} else if (preg_match('/Edge([\d]*)\/([^\s]+)/i', $agent, $regs)) {
    $str1 = explode('Edge/', $regs[0]);
$Edge_vern = explode('.', $str1[1]);
    $outputer = 'Edge '.$Edge_vern[0];
} else if (preg_match('/EdgiOS([\d]*)\/([^\s]+)/i', $agent, $regs)) {
    $str1 = explode('EdgiOS/', $regs[0]);
    $outputer = 'Edge';
} else if (preg_match('/UC/i', $agent)) {
          $str1 = explode('rowser/',  $agent);
$UCBrowser_vern = explode('.', $str1[1]);
    $outputer = 'UC浏览器 '.$UCBrowser_vern[0];
}else if (preg_match('/OPR/i', $agent)) {
          $str1 = explode('OPR/',  $agent);
$opr_vern = explode('.', $str1[1]);
    $outputer = '欧朋浏览器 '.$opr_vern[0];
} else if (preg_match('/MicroMesseng/i', $agent, $regs)) {
    $outputer = '微信内嵌浏览器';
}  else if (preg_match('/WeiBo/i', $agent, $regs)) {
    $outputer = '微博内嵌浏览器';
}  else if (preg_match('/QQ/i', $agent, $regs)||preg_match('/QQBrowser\/([^\s]+)/i', $agent, $regs)) {
              $str1 = explode('rowser/',  $agent);
$QQ_vern = explode('.', $str1[1]);
    $outputer = 'QQ浏览器 '.$QQ_vern[0];
} else if (preg_match('/MQBHD/i', $agent, $regs)) {
              $str1 = explode('MQBHD/',  $agent);
$QQ_vern = explode('.', $str1[1]);
    $outputer = 'QQ浏览器 '.$QQ_vern[0];
} else if (preg_match('/BIDU/i', $agent, $regs)) {
    $outputer = '百度浏览器';
} else if (preg_match('/LBBROWSER/i', $agent, $regs)) {
    $outputer = '猎豹浏览器';
} else if (preg_match('/TheWorld/i', $agent, $regs)) {
    $outputer = '世界之窗浏览器';
} else if (preg_match('/XiaoMi/i', $agent, $regs)) {
    $outputer = '小米浏览器';
} else if (preg_match('/UBrowser/i', $agent, $regs)) {
          $str1 = explode('rowser/',  $agent);
$UCBrowser_vern = explode('.', $str1[1]);
    $outputer = 'UC浏览器 '.$UCBrowser_vern[0];
} else if (preg_match('/mailapp/i', $agent, $regs)) {
    $outputer = 'email内嵌浏览器';
} else if (preg_match('/2345Explorer/i', $agent, $regs)) {
    $outputer = '2345浏览器';
} else if (preg_match('/Sleipnir/i', $agent, $regs)) {
    $outputer = '神马浏览器';
} else if (preg_match('/YaBrowser/i', $agent, $regs)) {
    $outputer = 'Yandex浏览器';
}  else if (preg_match('/Opera[\s|\/]([^\s]+)/i', $agent, $regs)) {
    $outputer = 'Opera浏览器';
} else if (preg_match('/MZBrowser/i', $agent, $regs)) {
    $outputer = '魅族浏览器';
} else if (preg_match('/VivoBrowser/i', $agent, $regs)) {
    $outputer = 'vivo浏览器';
} else if (preg_match('/Quark/i', $agent, $regs)) {
    $outputer = '夸克浏览器';
} else if (preg_match('/mixia/i', $agent, $regs)) {
    $outputer = '米侠浏览器';
}else if (preg_match('/fusion/i', $agent, $regs)) {
    $outputer = '客户端';
} else if (preg_match('/CoolMarket/i', $agent, $regs)) {
    $outputer = '基安内置浏览器';
} else if (preg_match('/Thunder/i', $agent, $regs)) {
    $outputer = '迅雷内置浏览器';
} else if (preg_match('/Chrome([\d]*)\/([^\s]+)/i', $agent, $regs)) {
$str1 = explode('Chrome/', $agent);
$chrome_vern = explode('.', $str1[1]);
    $outputer = '<i class="fa fa-chrome"></i> Chrome '.$chrome_vern[0];
} else if (preg_match('/safari\/([^\s]+)/i', $agent, $regs)) {
     $str1 = explode('Version/',  $agent);
$safari_vern = explode('.', $str1[1]);
    $outputer = 'Safari '.$safari_vern[0];
} else{
    return false;
}

return $outputer;
}

/** 获取操作系统信息 */

function getOs($agent){

$os = false;
if (preg_match('/win/i', $agent)) {
    if (preg_match('/nt 6.0/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows Vista';
    } else if (preg_match('/nt 6.1/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows 7';
    } else if (preg_match('/nt 6.2/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows 8';
    } else if(preg_match('/nt 6.3/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows 8.1';
    } else if(preg_match('/nt 5.1/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows XP';
    } else if (preg_match('/nt 10.0/i', $agent)) {
        $os = '<i class="fa fa-windows"></i> Windows 10';
    } else{
        $os = '<i class="fa fa-windows"></i> Windows';
    }
} else if (preg_match('/android/i', $agent)) {
if (preg_match('/android 9/i', $agent)) {
    $os = '<i class="fa fa-android"></i> Android P';
}
else if (preg_match('/android 8/i', $agent)) {
    $os = '<i class="fa fa-android"></i> Android O';
}
else if (preg_match('/android 7/i', $agent)) {
    $os = '<i class="fa fa-android"></i> Android N';
}
else if (preg_match('/android 6/i', $agent)) {
    $os = '<i class="fa fa-android"></i> Android M';
}
else if (preg_match('/android 5/i', $agent)) {
    $os = '<i class="fa fa-android"></i> Android L';
}
else{
    $os = '<i class="fa fa-android"></i> Android';
    }
}
else if (preg_match('/ubuntu/i', $agent)) {
    $os = '<i class="fa fa-linux"></i> Linux';
} else if (preg_match('/linux/i', $agent)) {
    $os = '<i class="fa fa-linux"></i> Linux';
} else if (preg_match('/iPhone/i', $agent)) {
    $os = '<i class="fa fa-apple"></i> iPhone';
} else if (preg_match('/iPad/i', $agent)) {
    $os = '<i class="fa fa-apple"></i> iPad';
} else if (preg_match('/mac/i', $agent)) {
    $os = '<i class="fa fa-OSX"></i> OSX';
}else if (preg_match('/cros/i', $agent)) {
    $os = 'chrome os';
}else {
return false;
}

return $os;
}

添加完成后,再在你所使用的主题评论模板comments.php文件,在您想显示的位置加上如下代码。

<span class="agent"><?php echo getOs($comments->agent); ?></span>
<span class="agent"><?php echo getBrowser($comments->agent); ?></span>

(PS:本博客实现网站评论者UA本站所使用的是插件,效果是一样的。)
至此,你的网站评论处就会出现浏览器及操作系统。注意,博主使用的是下载的图片,如您也想要和博主一样的效果,可以联系博主,留下邮箱联系方式,博主可以发给你,或者你也可以使用awesome的图标,去font awesome官网下载图标包或直接引用其官网的BootstrapCDN即可,否则不会出现图片或者图标。

二、实现IP转真实地址并显示

其实网上的方法一共有两种,一种是利用淘宝、新浪、百度等的IP地址查询API进行查询并通过截取字段进行前台显示。博主上午使用了百度地图的IP API,但有一些小BUG。博主是个追求完美的人,所以就舍弃了。所以就求教祭华博客大佬获得了第二种方法,也就是本站用的方法。第二种就是博主使用的方法,利用纯真IP数据库进行服务器本地查询。此方法的好处是速度快,坏处就是需要定期更新数据库,不过网上更新纯真数据库的教程很多,这里就不赘述了。

继续讲解教程,将下方代码放入你所使用的主题的functions.php文件中。

/** 获取评论者地址 */

function convertip($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数据库路径不对';  

}
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 'System Error';  
} 
$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 '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 = '可能来自火星';  

}
$ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr); //转换编码
return $ipaddr;
}

注意,此代码的文件需和QQWry.Dat放在同一级目录,否则就需要修改$dat_path的数据库地址。

添加完成后,再次打开主题评论模板comments.php文件,在您想显示的位置加上如下代码。

<?php echo convertip($comments->ip); ?>

此时,评论者的IP地址就转换成了真实地址,受数据库影响,其真实地址不一定准确哈。

同时,Typecho配置CDN后获取访客真实IP地址可能会受到影响,请在Typecho站点根目录里的config.inc.php添加下面这段代码即可。

//绕过 CDN 代理IP获取客户真实IP地址
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = $list[0];
}

博主根据教程使用后,发现IP转换的真实地址后面有一个联通、移动、电信等运营商后缀,不太美观,所以又去请教了祭华大佬,将上述代码$ipaddr = "$ipAddr1 $ipAddr2";中的$ipAddr2去掉即可完美去掉运营商后缀。想要后缀的小伙伴可以不用去掉哈。

至此,关于在Typecho中显示网站评论者 UA 及 IP 转真实地址的教程结束。