本文最后更新于 96 天前,其中的信息可能已经有所发展或是发生改变。
结合上一篇文章,我们将套了CloudFlare的WordPress获取到评论者的真实IP后,就可以添加该功能了。
在网上翻阅了一遍,只找到这篇文章:WordPress实现评论显示IP归属地方法 – 技术教程 – 小宜技术猫 (azpay.cn)
先上效果
下载压缩包 上传到主题根目录
压缩包相关链接在文章底部1,把压缩包上传到主题的根目录,注意不是WordPress根目录。
编辑 functions.php
在php内添加一行代码:
include("useragent/ip2c-text.php");
编辑xxx-comment.php 模板
各个主题模板不同,我们需要在评论者用户后面,添加显示IP归属地、浏览器图标等信息,因此需要找到评论者的位置,查找方法:F12查看元素。 在合适位置添加代码如下:
convertip(get_comment_author_ip());
本主题需要修改function.php文件:
自动更新纯真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; // 或者返回原始字符串,或者根据你的需求进行其他处理
}
}
});
有么有typecho的
没有捏(/ω\)
评论显示 IP 归属地方法
加拿大啊,牛哇🤭