Joe 主题对接腾讯 LBS 展示 IP 属地(二)
侧边栏壁纸
  • 累计撰写 189 篇文章
  • 累计收到 1,259 条评论

Joe 主题对接腾讯 LBS 展示 IP 属地(二)

萧瑟
2023-06-08 / 7 评论 / 247 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年06月10日,已超过486天没有更新,若内容或图片失效,请留言反馈。

书接上回,我们在主题中对接腾讯LBS IP查询服务后,会有一个bug:如果某篇文章评论过多,则某些评论IP定位数据无法显示,这个是因为腾讯LBS服务个人开发者的并发量限制为5次/秒。在上一个教程发布后,也有大佬发现了这个问题,不过这个问题我顺手就解决了,但是解决方案没有分享出来,因为需要改typecho系统的代码。这个已经脱离技术小白的范围,请合理折腾,折腾前记得备份数据。

原理

这一次折腾的原理是,我们在数据库中添加一个字段作为IP属地信息的一个冗余信息;当用户评论时,获取用户IP地址,调用腾讯LBS服务进行查询,将查询到的数据写入数据库中,这样就避免并发量超出限制。

执行sql语句

23.06.10:根据Typecho数据库设计文档又更新了一下sql语句
ALTER TABLE `typecho_comments` 
ADD COLUMN `ipRegion` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'IP中文地址' AFTER `parent`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`coid`) USING BTREE;

上面sql就是在字段coid后增加一个ipRegion的字段,并且添加一个备注信息。

修改代码

我们打开网站根目录,路径:/var/Widget/Base/Comments.php

这个文件是系统评论对外提供的方法,包括插入数据和查询数据等方法,有能力的同学,可以翻翻代码,基本上面都有注释;

大概55行,也就是增加评论 的方法首行,增加以下代码,将key和sign_key修改为自己申请的就可以。

$ipRegion = '';
        $cip = empty($comment['ip']) ? $this->request->getIp() : $comment['ip'];
        $key = '配置自己申请的key';
        //签名校验的KEY
        $sign_key = '配置自己申请的sign_key'; 
        $sign = md5('/ws/location/v1/ip?ip='.$cip.'&key='.$key.$sign_key);
        $url = 'https://apis.map.qq.com/ws/location/v1/ip?ip='.$cip.'&key='.$key.'&sig='.$sign;
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_HTTPGET, true);
        curl_setopt($ch, CURLOPT_REFERER, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36');
        $content = curl_exec($ch);
        curl_close($ch);
        if($content) {
            $json = json_decode($content,true);
            if($json['status'] == 0 ){
                $resjson = $json['result']['ad_info'];
                if($resjson['nation'] == '中国'){
                    if($resjson['province']=='北京市'||$resjson['province']=='天津市'||$resjson['province']=='上海市'||$resjson['province']=='重庆市'){
                        $ipRegion = $resjson['city'];    
                    }else{
                        $ipRegion = $resjson['province'].$resjson['city'];    
                    }
                }else{
                    $ipRegion = $resjson['nation'].$resjson['province'].$resjson['city'].$resjson['district'];    
                }
            }
        }

上面代码增加完后,大概在108行,也就是构建插入结构 那行注释里面增加一个参数,把下面代码放在[]中,

'ipRegion'  =>  $ipRegion, 

在381行后,插入下面,这个就是把查询对象增加一个输出值

'table.comments.ipRegion'

基本上请求和写入已经完成,我们再改一下后台管理界面,把这个ip属地也添加到页面上,这样后台也方便查询

打开admin/manage-comments.php

136行后增加以下代码

<br /><span><?php $comments->ipRegion(); ?>

最后我们再来修改主题的评论,这里以Joe主题为例

文件路径joe/public/comment.php

<?php $comments->ipRegion(); ?> 

找到合适位置显示IP属地,我是放在112行的

<div class="agent">
  <?php $comments->ipRegion(); ?> <?php _getAgentOS($comments->agent); ?> · <?php _getAgentBrowser($comments->agent); ?>
</div>

最终效果如下

演示效果

评论 (7)

取消
  1. 头像
    obaby
    山东省青岛市 MacOS · Google Chrome

    看看归属地~~

    回复
  2. 头像
    玩技e族
    北京市 Windows 10 · Google Chrome

    现在都开始要求做这个了。

    回复
  3. 头像
    Dabenshi
    北京市 Windows 10 · Google Chrome

    对于评论展现信息,我曾接到过很多(反应暴露评论者信息,邮箱、IP位置等等,后来我清掉了评论数据表禁止评论, 再后2023年几月 我不记得了 为响应各位,重写评论 对外部(游客)隐藏私密信息)现在在考虑要不要把评论者域名地址放出来,还在找稳妥的办法,为什么这么说呢 之前我就遇到过 通过评论注入SQL获取数据 都是高手啊 所以稳妥了之后再放出来 上面的种种都是我个人经历 还得多学学大佬们

    回复
  4. 头像
    vian
    河南省郑州市 Windows 10 · Microsoft Edge

    来了来了 时隔一年 终于更新了 哈哈表情

    回复
    1. 头像
      萧瑟 作者
      北京市 Windows 10 · Microsoft Edge
      @ vian

      主要是忙忘了表情

      回复
  5. 头像
    网友小宋
    广东省东莞市 Windows 10 · Microsoft Edge

    真不错

    回复
  6. 头像
    昔年
    广东省广州市 Windows 10 · Google Chrome

    typecho 因你而精彩

    回复