WordPress “比温度”趣味功能开源发布
本文是《技术相关(共59篇)》目录的第 55 篇。阅读本文前,建议先阅读本文前3篇文章:
2025/08/08 修复了IP地址归属地为四大直辖市时,前台省份显示XX省而非XX市的问题;引入了ipinfo.io作为备用第一解析API,前台通过映射将后台代码、拼音或英文转换成中文;解除ip9.com.cn只解析IPV6的限制,现在同时支持解析IPV4和IPV6;提供调试代码。
2025/08/04 修复了IP地址归属地为香港特别行政区、澳门特别行政区和台湾省不显示的问题。
2025/08/02 适配了PHP8.4,可能修复了跨月今日温度排行榜和明日温度预测榜不显示的问题。
8月的第一天,突然发现大家评论了,但是今日温度排行榜和明日温度预测榜都不显示,原来是代码有问题,没有考虑跨月。之所以说可能修复了,是因为发现的晚了,修改完已经8月2号了,只能下个月初验证了。
今年的夏天格外炎热,于是在上周的某一天突发奇想,想在网友在本站发布评论后能够根据IP获取归属地依此通过API得到该地区的温度,最终看一看谁的城市温度最高。期间遇到了很多困难,主要的有2个,一是寻找一款合适免费的既支持IP归属地查询,又支持温度查询的API;二是对于IPV6非标准格式的归属地解析。在不断修改的过程中,先后得到了灵妹子Obaby、公子扶苏、全局变量、Vind、刘郎、满心、八对星星、瓦匠等各位朋友的帮助和留言支持,再次表示感谢。
功能实现的前提是需要安装WP-UserAgent插件,因为需要获取插件在comments数据表中存储在comment_author_IP的IP信息。强烈推荐灵妹子修改的WP-UserAgent [纯真增强版] 15.01.01,本站就是安装的这个,比温度的功能就是基于此开发。如果你有不同的插件也在数据库中存储的有IP信息,可以在后面的代码数据库查询语句中进行相应的修改。
经过不断的摸索与修正,最终选择米人mir6作为主力API,它同时支持解析IPV4/IPV6/昨日近日明日天气,并且是全部免费的。虽然每秒钟有迸发限制,但是申请完KEY后对于我这种流量小的个人站点而言完全够用。但是在使用中发现有些IPV6不能解析城市,最终选择ip9作为备用API,专门兜IPV6的底。
比温度的逻辑其实很简单,就是先评论本站,然后API根据存储在数据库中的IP地址解析归属地,再对归属地获取近3天的温度。由于免费版不支持实时温度,所以只能设定为评论日期当天的城市最高温度。获取的时间段均为00:00-23:59,且实行了去重机制,即游客名+归属地+评论日期均相同的,只显示一次,也就是同一天游客评论多次,只显示一次。考虑到不同的游客评论的时间不同,有的可能是早上,有的可能是中午,有的可能是半夜,所以为了公平公正,对温度引入了加权处理,但是排序还是按照原始温度排序,加权温度只是为了反应不同的时段内对温度感知的影响。为了减少API的资源占用,提高前台运行速度,减少对数据库的查询,采用了Redis缓存机制,并在宝塔面板建立了计划任务,每10分钟刷新一次排行。
只有先评论才能生成排行,明日预测只预测今天评论的游客所在城市的温度,激励大家明日还来评论。
今天23:59分的排行榜最终结果就是昨日排行榜的结果。

1、在WP主题的page(页面目录)下建立temperature.php和temperaturecache.php文件,其中temperature.php用来前台展示,temperaturecache.php用来后台获取及缓存刷新。
temperature.php代码如下:
其中以下语句控制温度立柱的长度
$width_percent = (($item['temp'] - $min_temp) / $temp_range) * 40 + 60;
$weight_factor = round($item['temp'] / $item['original_temp'], 2);
2、temperaturecache.php代码如下:
代码开头的// 统一的国家/地区映射表,如果前台显示的有拼音、英文或者国家代码,就按照我写好的格式映射一下,前台就显示称中文了。
代码开头的API配置,你需要到api.mir6.com注册登陆账号,在后台产品列表里购买以下2个产品,都是免费的,我都购买的了1年。作为备用API的ip9.com.cn不需要注册,也没有KEY。
购买后把下图myKey=后面的值填进去即可。
2、宝塔面板后台建立计划任务如下:
你可以在日志里查看数据是否获取成功。
大功告成!
以下是调试代码,当某IPV4/IPV6本代码无法正确完整解析,供大家调试:
找到:
$now = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
$today_start = $now->format('Y-m-d 00:00:00');
$today_end = $now->format('Y-m-d 23:59:59');
在它上面添加:
// 修改这里:例如直接指定2025-08-01作为查询日期,昨天温度排行榜就只显示这一天的排行
$specific_date = '2025-08-01';
$yesterday_start = $specific_date . ' 00:00:00';
$yesterday_end = $specific_date . ' 23:59:59';
同时屏蔽下方代码:
//$yesterday = clone $now;
//$yesterday->modify('-1 day');
//$yesterday_start = $yesterday->format('Y-m-d 00:00:00');
//$yesterday_end = $yesterday->format('Y-m-d 23:59:59');
将以下代码放到最后 ?>的前面
// ===== 调试代码 =====
function debug_ip_location(string $ip) {
echo str_repeat("=", 50) . "\n";
echo "调试IP地址: $ip\n";
$start_time = microtime(true);
// 强制清除缓存进行测试
$redis = init_redis();
if ($redis) {
$redis->del('ip_location_' . md5($ip));
}
// 主API调用过程
echo "\n[主API调用] mir6.com\n";
$api_url = "https://api.mir6.com/api/ip?myKey=".IP_API_KEY."&ip={$ip}&type=json";
$response = wp_remote_get($api_url, ['timeout' => 5]);
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
$data = json_decode(wp_remote_retrieve_body($response), true);
echo "响应数据: " . json_encode($data['data'] ?? [], JSON_UNESCAPED_UNICODE) . "\n";
} else {
echo "主API调用失败: " . (is_wp_error($response) ? $response->get_error_message() : "HTTP ".wp_remote_retrieve_response_code($response)) . "\n";
}
// 备用API调用过程
echo "\n[备用API调用] ipinfo.io\n";
$backup_url = "https://ipinfo.io/{$ip}/json";
if (IPINFO_API_KEY) {
$backup_url .= "?token=" . IPINFO_API_KEY;
}
$response = wp_remote_get($backup_url, ['timeout' => 5]);
if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
$data = json_decode(wp_remote_retrieve_body($response), true);
echo "响应数据: " . json_encode($data, JSON_UNESCAPED_UNICODE) . "\n";
} else {
echo "调用失败: " . (is_wp_error($response) ? $response->get_error_message() : "HTTP ".wp_remote_retrieve_response_code($response)) . "\n";
}
// 最终解析结果
echo "\n[最终解析结果]\n";
$location = get_cached_location($ip);
if ($location === false) {
echo "解析失败: 无法获取该IP的地理位置信息\n";
} else {
echo "国家: " . ($location['country'] ?? '未知') . "\n";
echo "省份: " . ($location['province'] ?? '未知') . "\n";
echo "城市: " . ($location['city'] ?? '未知') . "\n";
echo "数据来源: " . ($location['source'] ?? 'unknown') . "\n";
}
$elapsed = round((microtime(true) - $start_time) * 1000, 2);
echo "\n解析耗时: {$elapsed}ms\n";
echo str_repeat("=", 50) . "\n";
}
// 调试指定的IP地址
echo "\n\n===== 开始IP地址解析调试 =====\n";
debug_ip_location('你的IPV4/IPV6地址,一行一个'); // IPV4/IPV6地址
debug_ip_location('你的IPV4/IPV6地址,一行一个'); // IPV4/IPV6地址
echo "===== 调试结束 =====\n\n";
这样你会在宝塔计划任务日志里看到IPV4/IPV6非常详细的解析过程以及最终采用哪个解析结果。
您已阅读完《技术相关(共59篇)》目录的第 55 篇。请继续阅读本文后3篇文章:
威言威语
都是一些新奇的功能😎
似水流年
请大神予以指导。🤭
公子扶苏
高级的一笔,要哪里留言才能看到。。
似水流年
随便留言就可以在比温度页面看到,只不过我设置的是每10分钟刷新一次。
obaby
高级功能,哈哈哈
似水流年
多谢灵妹子。
爱娃子
厉害啊大佬👍
似水流年
爱娃子?亮娃子?我在你的博客找到了答案。😁