评论区显示用户IP归属地(写数据库)

前段时间给评论区增加了一个显示评论用户IP归属地的功能,实现的方式是获取评论用户的IP后,通过腾讯的API获得到IP归属地后展现出来。

利用这种方式虽然可以实现功能,但有一些小问题:

每次访问文章评论页面,都会调用腾讯的API进行一次查询,如果文章页的留言特别多,会导致页面加载变慢;
腾讯API给个人认证用户的并发量额度只有5次/秒,文章留言一多,只能查询到前几条评论的IP归属地,后面的所有评论都查询不到归属地。
于是在原有的基础上进行了一下改进,这里记录一下。

改进思路
通过查询wordpress文档,wordpress的评论有两张数据库表wp_comment和wp_commentmeta。

wp_comment表:用户存储评论信息,如评论内容、评论所属文章、评论人昵称、邮箱、URL 等
wp_commentmeta表:用户存储评论元数据等信息
那么这里就可以用上wp_commentmeta数据库表,在用户提交评论的时候,基于用户的IP查询到归属地后,将归属地写入到数据库表中。

写数据库表
使用wordpress自带的开发函数add_comment_meta(),该函数可以向评论添加元数据字段。

add_comment_meta( int $comment_id, string $meta_key, mixed $meta_value, bool $unique = false )

评论区显示用户IP归属地(写数据库)

function add_comment_meta($comment_id, $meta_key, $meta_value, $unique = false) {
return add_metadata('comment', $comment_id, $meta_key, $meta_value, $unique);
}

前端调用

前端需要显示就直接使用评论ID查询数据就可以得知归属地,这样一来就可以解决之前的两个问题了。

get_comment_meta( int $comment_id, string $key = ”, bool $single = false )

评论区显示用户IP归属地(写数据库)

function get_comment_meta($comment_id, $key = '', $single = false) {
return get_metadata('comment', $comment_id, $key, $single);
}

小问题
但随之而来的问题就是,只有新评论才会显示归属地,旧的评论无法显示,这里提供一个解决思路:

将旧评论的IP查询到归属地手工新增到数据库中(比较麻烦);
旧评论还使用之前的方式显示归属地(我是这么做的);
删掉所得旧评论(不建议)。

实现代码

//调用腾讯API基于IP获取IP归属地
function province($user_ip) {
if (filter_var($user_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_IPV4)) {
if (filter_var($user_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
$url = "https://apis.map.qq.com/ws/location/v1/ip?key=【腾讯API Key,不要方括号】&ip=" . $user_ip;
$UserAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; .NET CLR 3.5.21022; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_ENCODING, '');
curl_setopt($curl, CURLOPT_USERAGENT, $UserAgent);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($curl);
$data = json_decode($data, true);
$result = array_column($data, 'ad_info');
$nation = array_column($result, 'nation'); // 获取国家
$nation = array_shift($nation); // 获取国家
$province = array_column($result, 'province'); // 获取省份
$province = array_shift($province); // 获取省份
$ad_info = $nation == "中国" ? $province : $nation; // 判断,如果国家为中国,则显示省,否则显示国家
$ad_info = isset($ad_info) ? $ad_info : "未知IP";
return $ad_info;
} else {
return "私网用户";
}
} else {
return "未知IP";
}
}
//获取归属地并写入数据库
function add_comment_ipterritory($comment_id) {
$ipterritory = province($_SERVER['REMOTE_ADDR']);
$ipterritory = isset($ipterritory) ? wp_filter_nohtml_kses($ipterritory) : "未知IP";
add_comment_meta($comment_id, '_ipterritory', $ipterritory);
}
add_action ('comment_post', 'add_comment_ipterritory');
//后台增加归属地字段
function my_comments_columns( $columns ){
$columns[ '_ipterritory' ] = __( 'IP归属地' );
return $columns;
}
function  output_my_comments_columns( $column_name, $comment_id ){
switch( $column_name ){
case '_ipterritory';
echo get_comment_meta( $comment_id, '_ipterritory', true );
break;
add_filter( 'manage_edit-comments_columns', 'my_comments_columns' );
add_action( 'manage_comments_custom_column', 'output_my_comments_columns', 10, 2 );

输出

<?php $ipterritory = get_comment_meta($comment->comment_ID,'_ipterritory',true);echo empty($ipterritory)? province(get_comment_author_ip()) : $ipterritory ;?>

正文完
 0