[教程]给WordPress评论添加归属地

本期教程教大家如何给添加WordPress评论IP归属地。

[教程]给WordPress评论添加归属地-语络

下载压缩包上传到主题根目录

本站下载

把压缩包上的文件夹传到主题的根目录,注意不是 WordPress 根目录。

编辑 functions.php

在 php 内添加一行代码:

include("show-useragent/ip2c-text.php"); //显示用户IP
include("show-useragent/show-useragent.php"); //显示用户UA

编辑 comments.php 模板

各个主题模板不同,我们需要在评论者用户后面,添加显示 IP 归属地、浏览器图标等信息,因此需要找到评论者的位置,查找方法:F12 查看元素。 在合适位置添加代码如下:

<?php CID_print_comment_flag(); echo ' ';CID_print_comment_browser(); ?>
<?php
echo " ";echo "<span style='font-size:12px;color:#aaa;'>";
echo convertip(get_comment_author_ip());
echo "</span>";
?></span>

如果评论模板找不到评论者昵称,请到wp-includes/class-walker-comment.php中找到以下代码

<div class="comment-author vcard">
<?php
if ( 0 != $args['avatar_size'] ) {
echo get_avatar( $comment, $args['avatar_size'] );
}?>
<?php
$comment_author = get_comment_author_link( $comment );if ( '0' == $comment->comment_approved && ! $show_pending_links ) {
$comment_author = get_comment_author( $comment );
}printf(
/* translators: %s: Comment author link. */
__( '%s <span class="says">says:</span>' ),
sprintf( '<b class="fn">%s</b>', $comment_author )
);
?>
</div>

把上面代码放到合适位置,如下:

<div class="comment-author vcard">
<?php
if ( 0 != $args['avatar_size'] ) {
echo get_avatar( $comment, $args['avatar_size'] );
}
?>
<?php
$comment_author = get_comment_author_link( $comment );if ( '0' == $comment->comment_approved && ! $show_pending_links ) {
$comment_author = get_comment_author( $comment );
}printf(
/* translators: %s: Comment author link. */
__( '%s <span class="says">says:</span>' ),
sprintf( '<b class="fn">%s</b>', $comment_author )
);
?>
<?php CID_print_comment_flag(); echo ' ';CID_print_comment_browser(); ?>
<?php
echo " ";echo "<span style='font-size:12px;color:#aaa;'>";
echo convertip(get_comment_author_ip());
echo "</span>";
?></span>
</div>

自动更新纯真 IP 离线库

新建一个 php 文件,网络访问它,即可生成一个 dat 文件。源码已更改为 Github 源,原版的用不来。

这个文件我已经帮大家放在压缩包里面了,使用到宝塔面板的自动访问 URL 设置好时间,自动定期访问这个 update.php 文件就可以自动下载最新的纯真 IP 离线库了。

WordPress 实现评论显示 IP 归属地方法下载:
分享名称:useragent_rR6hY.zip
分享链接:https://kb.itpno.com/#s/-os-1sUw
访问密码:iTPno.

最近发现了报错,原因是没有 ipv6 字典,更新了免费输出 ipv6 归属地的方法:
方法就是将 ipv6 显示到页面上,然后通过 js 异步调用接口获取地址,为什么不用 php 实时,因为这样时间 php 返回就慢了,效果不好,而且还会出现超时等问题,因此用 js 前端去获取。而且 ipv6 目前没有免费的字典,其他家都是收费的,就这家免费分享,感谢 vv1234。。

ip2c-text.php:

<?php
function convertip($ip) {
$dat_path = dirname(__FILE__).'/qqwry.dat'; //*数据库路径*//
if(!$fd = @fopen($dat_path, 'rb')){
return 'IP date file not exists or access denied';
}
$ip = explode('.', $ip);
// 确保 IP 地址被正确分割为四个部分
if (count($ip) !== 4) {
if (count($ip) == 1){
return 'IPv6-<span class="ipv6">' . $ip[0] . "</span>";
}
return '未知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;
$ip1num = 0;
$ip2num = 0;
$ipAddr1 = '';
$ipAddr2 = '';
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 = 'Unknown';
}
$ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr);
if( $ipaddr != ' ' )
return $ipaddr;
else
$ipaddr = '火星来客';
return $ipaddr;
}
function getIpv6Data($ip,$token = 'test') {
$url = "https://api.vv1234.cn/ip/api.php?ip_url=" . urlencode($ip) . "&from=ip.vv1234.cn&token=" . urlencode($token) . "&code=json";
// 初始化 cURL 会话
$ch = curl_init();
// 设置 cURL 选项
curl_setopt($ch, CURLOPT_URL,$url); // 设置请求的 URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将返回结果作为字符串返回而不是直接输出
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用 SSL 证书验证(仅用于测试目的,实际使用中应启用验证)
// 执行 cURL 会话
$response = curl_exec($ch);
// 检查是否有 cURL 错误发生
if (curl_errno($ch)) {
// 如果有错误,关闭 cURL 会话并返回错误信息
curl_close($ch);
return "cURL Error: " . curl_error($ch);
}
// 关闭 cURL 会话
curl_close($ch);
// 解码 JSON 响应
$data = json_decode($response, true);
// 检查 JSON 解码是否成功
if (json_last_error() === JSON_ERROR_NONE) {
// 检查数据中是否包含所需的字段
if (isset($data['city'])) {
return $data['city']; // 返回城市信息
} else {
return "City information not found";
}
} else {
return "JSON decoding error";
}
}
?>

页面 js:

$(document).ready(function() {
// 查找所有class为ipv6的div
$('.ipv6').each(function() {
// 获取div中的内容,即ipv6地址
var ipv6Address = $(this).text();
// 构建请求URL
var requestUrl = 'https://api.vv1234.cn/ip/api.php?ip_url=' + encodeURIComponent(ipv6Address) + '&from=ip.vv1234.cn&token=test&code=json';
// 发起GET请求
$.get(requestUrl, function(data) {
// 示例使用
var jsonString = data;
var parsedJson = parseJsonSafely(jsonString);
console.log(parsedJson);
// 检查返回的数据是否正常
if (parsedJson && parsedJson.ip && parsedJson.city) {
// 如果正常,则替换div的内容为city字段
$(this).text(parsedJson.city);
}
// 如果没有正常返回,则不做调整
}.bind(this)).fail(function() {
// 处理请求失败的情况
console.log('请求失败,没有替换内容。');
});
});
function removeControlCharacters(str) {
// 使用正则表达式匹配并替换掉控制字符
return str.replace(/[\x00-\x1F\x7F-\x9F]/g, '');
}
function replaceControlCharactersWithSpace(str) {
// 使用正则表达式匹配并替换控制字符为空格
return str.replace(/[\x00-\x1F\x7F-\x9F]/g, ' ');
}
function parseJsonSafely(str) {
try {
// 移除控制字符
// str = removeControlCharacters(str);
// 替换控制字符为空格
str = replaceControlCharactersWithSpace(str);
// 尝试解析JSON
return JSON.parse(str);
} catch (e) {
// 如果解析失败,打印错误信息
console.error("Error parsing JSON:", e);
return null; // 或者返回原始字符串,或者根据你的需求进行其他处理
}
}
});

有些主题并不显示评论者真实的IP地址,而是显示局域网IP。解决方法:需要将下面的代码放进functions.php

温馨提示:此处内容需要您 回复评论 后才能查看