主题评论区展示用户归属地
本文最后更新于308 天前,其中的信息可能已经过时,如有错误请发送邮件到[email protected]

经过两天下班时间的弯弯绕绕,终于实现了在评论区展示用户归属地的功能,在此记录分享一下。

修改主题functions

首先在主题functions.php文件中添加以下代码。

/** * 根据百度IP查询接口获取IP所在地 */ 
function getCity($ip) {
    //百度api的接口

    $url = "https://opendata.baidu.com/api.php?query=".$ip."&co=&resource_id=6006&format=json&oe=utf8";
    $ip=json_decode(file_get_contents($url),true);
	$out = "<div class='comment-useragent'>";
    if($ip['status']=='0'){
        $out .= "<i class='fa fa-globe'; style='color:blue';></i>" ." ".$ip['data'][0]['location'];
        /*  如果想使用自定义图标库,可以把上面的“$out .=”后面的内容替换成以下代码,在按自定义图标部分的内容进行操作
        $out .= $GLOBALS['UA_ICON']['City2'] ." ".$ip['data'][0]['location'];
        */
    }else{
        return false;
    }
    $out .= "</div>";
    return apply_filters("argon_comment_ua_icon", $out);
}

在functions.php中定位到以下代码位置

echo parse_ua_and_icon($comment -> comment_agent);

在这段代码后面添加如下内容,以调用上面定义的功能块。

<?php
    echo getCity(get_comment_author_ip());
?>

自定义图标

找到useragent-parser.php文件,在最后添加以下代码,用于在归属地前添加图标。

$GLOBALS['UA_ICON']['City2'] = '<svg >……</svg>';

上述代码里的”<svg >……</svg>“,替换成自己下载的svg代码,格式可参照useragent-parser.php文件的原有内容。

解析

下面的代码是百度的IP归属地在线查询API返回的JSON结果(已将真实IP隐去)。

{
    "status": "0",
    "t": "",
    "set_cache_time": "",
    "data": [
        {
            "ExtendedLocation": "",
            "OriginQuery": "123.123.123.123",
            "appinfo": "",
            "disp_type": 0,
            "fetchkey": "123.123.123.123",
            "location": "福建省福州市 电信",
            "origip": "123.123.123.123",
            "origipquery": "123.123.123.123",
            "resourceid": "6006",
            "role_id": 0,
            "shareImage": 1,
            "showLikeShare": 1,
            "showlamp": "1",
            "titlecont": "IP地址查询",
            "tplt": "ip"
        }
    ]
}

返回结果中,status=0表示请求成功,但是不表示有数据返回,data集合不为空才表示查询成功。

根据以上,可知代码作用如下:

设置API接口参数;format:设置返回结果的格式,支持json,xml,json。

$url = "https://opendata.baidu.com/api.php?query=".$ip."&co=&resource_id=6006&format=json&oe=utf8";

判断请求是否成功,若请求不成功,则不显示归属地。

if($ip['status']=='0')
{
    ……
}else{
    return false;
}
$out .= "<i class='fa fa-globe'; style='color:blue';></i>" ." ".$ip['data'][0]['location'];

返回的JSON结果中”data”里的地理位置,需要根据不同API返回的JSON结果修改“$ip”之后的部分。

离线IP归属地接口

在网络上搜寻的时候也看到了一个使用纯真IP数据库作为离线IP归属地接口的方法:WordPress获取真实IP,以及将IP转换成归属地,来自 Gimhoy’s Blog,搬运在此进行一个记录!

调用QQ IP数据库

纯真IP数据库也就是QQ IP数据库纯真版,收集了包括中国电信、中国网通、长城宽带、网通宽带、聚友宽带等 ISP 的 IP 地址数据。

使用方法:百度下载QQ IP数据库纯真版,将其中的QQWry.Dat放入主题目录下。然后在当前主题下的functions.php中加入以下代码

//IP转地址
function convertip($ip) {
    $dat_path = TEMPLATEPATH.'/QQWry.Dat';
    if(!$fd = @fopen($dat_path, 'rb')){
        return 'IP date file not exists or access denied';
    }
    $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 = 'Unknown';
    }
    $ipaddr = iconv('gbk', 'utf-8//IGNORE', $ipaddr); 
    if( $ipaddr != '  ' )
        return $ipaddr;
    else
        $ipaddr = '地址未知!火星来客?';
        return $ipaddr;
}

使用的时候调用这个函数即可。

调用IP归属地函数

将IP转换成归属地在WordPress中的应用:在评论列表/后台评论列表/评论通知邮件中显示评论者IP所在地

在主题目录下的functions.php中,找到评论列表,大概搜get_comment_author_link()即可,在合适的位置加上下面的代码:

<?php if ( is_user_logged_in() ) echo convertip(get_comment_author_ip()); //回复者所在地及网络 ?>

这里用到了《WordPress获取真实IP,以及将IP转换成归属地》中创建的convertip函数,如果用的是其他的IP地址转换函数,修改一下代码中的函数名称即可。如果没有转换IP的函数,请先加入,方法见上文。

同时感谢博主鸦鸦的巢穴,提供了一种使用离线地图插件的思路!

淘宝API接口

以下是网上找的淘宝IP归属地API接口代码,以及相关说明

/*    淘宝API,不对个人开放
    $url="https://ip.taobao.com/outGetIpInfo?ip=".$ip;
    $ip=json_decode(file_get_contents($url));
    if((string)$ip->code=='4'){
        return "个人qps超出";
    }
    $data = (array)$ip->data;
    return $data;
*/

1. 请求接口(GET,POST):

/outGetIpInfo?ip=[ip地址字串]&accessKey=[访问密匙]

2. 响应信息:

(json格式的)国家 、省(自治区或直辖市)、市(县)、运营商

3. 返回数据格式:

{“code”:0,”data”:{“ip”:”210.75.225.254″,”country”:”\u4e2d\u56fd”,”area”:”\u534e\u5317″,
“region”:”\u5317\u4eac\u5e02″,”city”:”\u5317\u4eac\u5e02″,”county”:””,”isp”:”\u7535\u4fe1″,
“country_id”:”86″,”area_id”:”100000″,”region_id”:”110000″,”city_id”:”110000″,
“county_id”:”-1″,”isp_id”:”100017″}}
其中code的值的含义为,0:成功,1:服务器异常,2:请求参数异常,3:服务器繁忙,4:个人qps超出。

淘宝IP地址库接口说明

由于自己不太懂PHP语法,以及没有认真研究Argon主题的逻辑结构,在添加的时候也经过了一些失败。但是,最重要的是,一开始没注意到使用的IP归属地在线查询API (ip.taobao.com)是无效的、是已不对个人开放的!导致我一直以为是我插入的方式不对,(;´༎ຶД༎ຶ`) 。

评论

  1. wlli
    Windows Edge
    贵州省贵阳市 电信
    10 月前
    2023-12-09 20:00:58

    厉害

发送评论 编辑评论


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