背景
typecho留言评论增加IP地址定位归属地信息入库存储,即在访客提交评论时同步存储访客的IP地址定位归属地,便于直接输出显示。
虽然目前有插件能动态解析IP地址归属地并呈现,但缺点是较容易触发各地图开放平台IP定位服务的每秒并发量约定上限。
本文基于Typecho 1.2.1环境编写。最后更新于2023-11-30 15:08:56 星期四
增加步骤 1. 评论数据表(comments)增加IP归属地字段ipLocation ```sql alter table comments add ipLocation varchar(64) default NULL comment 'IP归属地'; ```
-
评论基类文件修改 /var/Widget/Base/Comments.php (1)增加ip地址解析方法 ```php //根据ip地址获取归属地 By:未来往事 2023/11/29 public function getIpLocation($ip){ $json = file_get_contents('https://apis.map.qq.com/ws/location/v1/ip?ip='.$ip.'&key=填入你在腾讯地图申请的秘钥'); $array = json_decode($json, true); $status = $array['status']; $province = $array['result']['ad_info']['province']; $city = $array['result']['ad_info']['city']; if ($array['status'] == 0) { if (in_array($province, array('北京市', '天津市', '上海市', '重庆市'))) { $location = $city; } else if (empty($province)) { $location = '未知'; } else { $location = $province.' / '.$city; } } else if (empty($ip) || $ip == '127.0.0.1') { $location = '未知'; } else { //$location = $status; $location = ''; } return $location; } ``` (2)insert插入方法修改 在public function insert(array $rows): int方法内插入结构$insertStruct函数后增加 ```php /** 获取ip归属地并入库 */ $ipLocation = $this->getIpLocation($insertStruct['ip']); if($ipLocation != ''){ $insertStruct['ipLocation'] = $ipLocation; } ``` 完整示例: ```php public function insert(array $rows): int { /** 构建插入结构 */ $insertStruct = [ ............ ];
/** 获取ip归属地并入库 */ $ipLocation = $this->getIpLocation($insertStruct['ip']); if($ipLocation != ''){ $insertStruct['ipLocation'] = $ipLocation; } ............
(3)修改查询方法,增加'table.comments.ipLocation'
/** * 获取查询对象 * * @return Query * @throws Exception */ public function select(): Query { return $this->db->select( ............, 'table.comments.ipLocation' ) ->from('table.comments'); }
- 调用显示IP定位归属地 修改评论归档组件类文件var/Widget/Comments/Archive.php, 找到 "threadedCommentsCallback" 评论回调函数,在适当位置插入以下代码,例如我们在评论时间之后插入: ```php if($this->ipLocation != ''){ //如果存储的有IP地址归属地,则直接输出 echo 'IP 属地:'.$this->ipLocation.''; } ``` **特殊情况:** - 某些主题会对评论列表使用 threadedComments 进行自定义,此时,需要在其函数体内适当位置添加以上代码,注意匹配参数 $this - 例如:你的主题使用 threadedComments($comments, $options) 对评论列表进行自定义时,则调用插件的代码为: ```php if($comments->ipLocation != ''){ //如果存储的有IP地址归属地,则直接输出 echo 'IP 属地:'.$comments->ipLocation.''; } ```