【教程】给WordPress评论添加归属地
本文最后更新于 74 天前,其中的信息可能已经有所发展或是发生改变。

结合上一篇文章,我们将套了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离线库了。

  1. 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; // 或者返回原始字符串,或者根据你的需求进行其他处理
      }
    }
});

评论

  1. 小菜集
    Windows Chrome 129.0.0.0 来自 中国–云南–大理白族自治州 移动
    2 月前
    2024-10-13 2:22:35

    有么有typecho的

    • 博主
      小菜集
      Windows Edge 129.0.0.0 来自 IPv6-2001:df1:7880:2::1371
      2 月前
      2024-10-13 12:26:49

      没有捏(/ω\)

  2. 安迪
    Windows Chrome 128.0.0.0 来自 美国–加利福尼亚州–洛杉矶–洛杉矶 IPXO
    3 月前
    2024-8-27 15:23:27

    评论显示 IP 归属地方法

    • 博主
      安迪
      iPhone AppleWebKit 605.1.15 来自 中国–浙江–宁波 电信
      3 月前
      2024-8-27 15:38:14

      加拿大啊,牛哇🤭

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Source: https://github.com/MengXi2021/Argon-Emoji-DailyNotes
Source: https://github.com/Ghost-chu/argon-huhu-emotions
https://github.com/qs5667/argon_bilibili_emoji
https://github.com/qs5667/argon_bilibili_emoji
https://github.com/qs5667/argon_bilibili_emoji
https://github.com/qs5667/argon_bilibili_emoji
Source: github.com/zhheo/Sticker-Heo
颜文字
Emoji
小恐龙
花!
每日手帐
呼呼
B站基础表情
B站节日表情
B站游戏表情
B站活动表情
Heo
上一篇
下一篇