版本:1.2.0 · 作者:yefengs · 协议:GPL v2 or later
项目地址:https://cnb.cool/yefengs/yue-location
悦·Location 是一款轻量、纯离线的 WordPress 插件,通过 ip2region 离线数据库实现 IP 归属地查询,并将结果自动展示在评论者昵称旁边。无需调用任何第三方 API,完全本地运行,保护用户隐私,查询延迟极低。
效果示意:
张三 📍 中国 · 广东 · 深圳
评论内容...
John 🌐 United States · California · Los Angeles
Comment content...
| 功能 | 说明 |
|---|---|
| IPv4 / IPv6 自动识别 | 自动判断 IP 版本,分别查询对应数据库,无需手动配置 |
| 离线数据库查询 | 基于 ip2region xdb 格式,无需联网,无 API 限制 |
| 前台评论自动展示 | 在评论者名称后自动追加归属地,无需修改主题 |
| 后台评论归属地列 | 在 WordPress 后台评论列表中新增"IP归属地"列 |
| 文章发布者定位 | 记录并展示每篇文章首次发布时的作者 IP 归属地 |
| 6 种内置图标 | 定位标记、地图、地球、旗帜、盾牌、指南针 SVG 图标 |
| IPv6 标识徽章 | IPv6 来源评论自动显示绿色 IPv6 标识 |
| 内存向量索引缓存 | 约占用 512 KB 内存,查询速度提升约 10 倍 |
| 丰富的主题 API | 提供 6 个全局函数,供主题开发者灵活调用 |
| 自定义 CSS | 支持自定义样式,也可关闭默认样式自行控制 |
| 安全数据清理 | 所有用户提交的数据均经过 sanitize_* 处理 |
| 项目 | 要求 |
|---|---|
| WordPress | ≥ 5.0(已在 6.9.4 上测试通过) |
| PHP | ≥ 7.4 |
| 文件权限 | 插件目录下的 .xdb 文件需要可读(0644 即可) |
/wp-content/plugins/yue-location/:
yue-location.php — 插件主文件ip2region_v4.xdb — IPv4 离线数据库ip2region_v6.xdb — IPv6 离线数据库yue-location.zip。注意: 两个
.xdb数据库文件是必须的。缺少任一文件,对应 IP 版本将无法查询。激活后在 设置 → 悦·Location 顶部可看到数据库状态检查。
yue-location/
├── yue-location.php 插件主文件(含核心查询类、主插件类、全局函数)
├── ip2region_v4.xdb IPv4 离线数据库(ip2region xdb 格式)
├── ip2region_v6.xdb IPv6 离线数据库(ip2region xdb 格式)
└── README.md 本说明文档
主文件内部结构:
yue-location.php
├── YueLocation_Searcher_Util 工具类(IP解析、字节读取、头部加载)
├── YueLocation_Searcher xdb 搜索器(支持向量索引缓存、文件流两种模式)
├── Yue_Location 插件主类(WordPress 集成、设置管理、钩子注册)
│ ├── init() 注册所有 WordPress 钩子
│ ├── query_location() 核心查询方法(返回结构化数组)
│ ├── format_location() 格式化归属地为 HTML 文本
│ ├── filter_comment_author() 前台评论钩子回调
│ ├── save_post_location() 文章发布者定位保存
│ └── render_settings_page() 后台设置页面渲染
└── 全局函数
├── Yue_get_location()
├── the_Yue_location()
├── Yue_get_location_raw()
├── Yue_get_location_by_comment()
├── Yue_get_post_location()
└── the_Yue_post_location()
进入 WordPress 后台 → 设置 → 悦·Location 进行配置。
| 选项 | 默认值 | 说明 |
|---|---|---|
| 图标风格 | 定位标记(实心) | 选择归属地前的装饰图标样式,可视化预览选择 |
| 归属地前缀文字 | 空 | 在归属地信息前追加的文字,例如填写「来自」后显示:来自中国 · 广东 · 深圳 |
| 字段分隔符 | · | 各归属地字段之间的分隔符,可改为空格、逗号、/ 等 |
可用图标风格:
| 标识 | 名称 | 说明 |
|---|---|---|
none | 不显示图标 | 仅显示文字,无图标 |
pin | 定位标记(实心) | 地图定位标记 SVG,默认选项 |
map | 地图图标 | 折叠地图 SVG |
globe | 地球图标 | 地球线条 SVG |
flag | 旗帜图标 | 旗帜 SVG |
shield | 盾牌图标 | 盾牌 SVG |
compass | 指南针图标 | 指南针 SVG |
选择要在归属地信息中展示的字段,至少勾选一个。
| 选项 | 默认 | 示例值 |
|---|---|---|
| 国家 | ✅ 开启 | 中国、美国、日本 |
| 省份 | ✅ 开启 | 广东省、加利福尼亚州 |
| 城市 | ✅ 开启 | 深圳市、洛杉矶 |
| ISP / 运营商 | ❌ 关闭 | 电信、联通、移动、阿里云 |
| ISO 国家代码 | ❌ 关闭 | CN、US、JP |
| 显示 IPv6 标识 | ✅ 开启 | 为 IPv6 评论显示绿色 IPv6 徽章 |
去重逻辑: 当省份名称与城市名称相同时,插件会自动去重,只显示一个,避免出现"广东 · 广东"等重复情况。
| 开关 | 默认 | 说明 |
|---|---|---|
| 前台评论自动显示 | ✅ 开启 | 在前台所有评论的作者名称后自动追加归属地。关闭后仍可手动调用模板函数 |
| 后台评论列表自动显示 | ✅ 开启 | 在后台「评论」列表中新增"IP归属地"列,同时显示完整 IP 地址 |
| 文章/页面发布者定位 | ❌ 关闭 | 文章首次发布时自动记录发布者 IP 归属地,写入 post_meta 和文章标签 |
| 正文中显示发布者定位 | ✅ 开启 | 开启后在文章正文末尾自动追加发布者归属地标签(依赖上一个开关) |
文章发布者定位功能详解:
📍 国家、📍 省份、📍 城市 格式写入文章标签,支持通过标签归档浏览publish(公开)和 private(私密)状态的 post、page 类型| 选项 | 默认 | 说明 |
|---|---|---|
| 内存缓存加速 | ✅ 开启 | 加载向量索引到内存(约 512 KB),查询速度提升约 10 倍 |
| 默认样式输出到前端页面 | ✅ 开启 | 是否在 <head> 中输出插件内置的 CSS 样式 |
| 开启自定义 CSS | ❌ 关闭 | 开启后,下方文本框中的自定义 CSS 会随页面输出 |
| 自定义 CSS | 空 | 自定义样式代码,支持覆盖所有内置 CSS 类 |
默认样式与自定义 CSS 相互独立,可同时开启、单独开启,或全部关闭由主题接管。
所有函数均以 function_exists() 保护声明,即使插件未启用也不会导致主题报错。调用前务必检查函数是否存在。
查询并返回格式化后的归属地 HTML 字符串(含图标、样式类)。
| 参数 | 类型 | 说明 |
|---|---|---|
$ip | string | IP 地址字符串,支持 IPv4 和 IPv6 |
返回值: string — 完整的 HTML 片段,失败返回空字符串。
// 示例
$html = Yue_get_location( '202.96.134.133' );
// 返回:<span class="yue-location"><svg ...></svg>中国 · 广东 · 深圳</span>
直接 echo 输出归属地 HTML,等同于 echo Yue_get_location( $ip )。
the_Yue_location( get_comment_author_IP() );
查询并返回原始归属地数据数组,适合需要自定义格式化的场景。
返回值: array|null
[
'country' => '中国', // 国家名称
'province' => '广东省', // 省份名称
'city' => '深圳市', // 城市名称
'isp' => '电信', // ISP/运营商
'iso' => 'CN', // ISO Alpha-2 国家代码
'is_v6' => false, // 是否为 IPv6 地址
]
根据评论对象或评论 ID 自动提取 IP 并返回格式化的归属地 HTML。
| 参数 | 类型 | 说明 |
|---|---|---|
$comment | WP_Comment|int | 评论对象或评论 ID |
返回值: string — 格式化的 HTML,失败返回空字符串。
echo Yue_get_location_by_comment( get_comment() );
echo Yue_get_location_by_comment( 42 ); // 通过评论 ID
获取指定文章的发布者归属地 HTML(从 post_meta 缓存读取,无额外查询开销)。
| 参数 | 类型 | 说明 |
|---|---|---|
$post | int|WP_Post|null | 文章 ID 或对象,默认为当前文章($post 全局变量) |
返回值: string — 格式化的 HTML,无记录返回空字符串。
echo Yue_get_post_location(); // 当前文章
echo Yue_get_post_location( 123 ); // 指定文章 ID
直接 echo 输出文章发布者归属地 HTML,等同于 echo Yue_get_post_location( $post )。
the_Yue_post_location(); // 在模板中直接输出
文章首次发布时,插件将以下三个 post_meta 字段写入数据库:
| meta_key | 类型 | 内容 |
|---|---|---|
_Yue_location_data | array | 完整数据:ip、location(数组)、text(格式化文本)、saved_at(保存时间) |
_Yue_location_ip | string | 发布者 IP 地址 |
_Yue_location_text | string | 格式化后的归属地文本(如"中国 · 广东 · 深圳") |
以下划线开头的 meta_key 为隐藏字段,不会出现在后台「自定义字段」面板中。
适用于需要自定义评论位置的场景(关闭自动显示时使用):
<div class="comment-author">
<?php comment_author(); ?>
<?php if ( function_exists( 'the_Yue_location' ) ) : ?>
<?php the_Yue_location( get_comment_author_IP() ); ?>
<?php endif; ?>
</div>
<?php if ( function_exists( 'Yue_get_location_raw' ) ) : ?>
<?php
$loc = Yue_get_location_raw( get_comment_author_IP() );
if ( $loc ) {
$parts = array_filter( [
$loc['country'],
$loc['province'],
$loc['city'],
] );
echo '<span class="my-location">' . esc_html( implode( ' · ', $parts ) ) . '</span>';
}
?>
<?php endif; ?>
<?php if ( function_exists( 'Yue_get_location_by_comment' ) ) : ?>
<?php echo Yue_get_location_by_comment( get_comment() ); ?>
<?php endif; ?>
<div class="entry-meta">
<span class="posted-on"><?php the_date(); ?></span>
<span class="comments-link"><?php comments_popup_link(); ?></span>
<?php if ( function_exists( 'the_Yue_post_location' ) ) : ?>
<?php the_Yue_post_location(); ?>
<?php endif; ?>
</div>
<?php
// 读取完整预存数据
$data = get_post_meta( get_the_ID(), '_Yue_location_data', true );
if ( $data ) {
echo '发布 IP:' . esc_html( $data['ip'] );
echo '国家:' . esc_html( $data['location']['country'] );
echo '发布于:' . esc_html( $data['saved_at'] );
}
// 仅读取格式化文本
$text = get_post_meta( get_the_ID(), '_Yue_location_text', true );
if ( $text ) {
echo '发布于 ' . esc_html( $text );
}
?>
<?php if ( function_exists( 'Yue_get_location' ) ) : ?>
<?php
// 查询当前访问者 IP
$visitor_ip = $_SERVER['REMOTE_ADDR'];
echo Yue_get_location( $visitor_ip );
// 查询指定 IP
echo Yue_get_location( '8.8.8.8' );
?>
<?php endif; ?>
| 类名 | 作用 |
|---|---|
.yue-author-wrapper | 评论作者名称的外层包裹容器(inline-flex) |
.yue-location | 归属地标签容器(图标 + 文字) |
.yue-icon | SVG 图标元素(14×14,默认透明度 0.6) |
.yue-ipv6-badge | IPv6 标识徽章(绿色圆角标签) |
.yue-post-location | 文章发布者归属地容器 |
.yue-post-location-meta | 文章 meta 区域的归属地容器(胶囊样式) |
.yue-post-location-label | 「发布于」文字标签 |
.yue-post-location-value | 归属地值的容器 |
在「自定义 CSS」中输入以下代码,可自定义归属地颜色:
/* 修改归属地文字颜色 */
.yue-location {
color: #888;
font-size: 0.85em;
}
/* 修改图标颜色 */
.yue-icon {
color: #c8655e;
opacity: 0.8;
}
/* 修改 IPv6 徽章样式 */
.yue-ipv6-badge {
background: #e3f2fd;
color: #1565c0;
}
/* 文章 meta 归属地样式 */
.yue-post-location-meta {
background: #fff5f4;
border-color: #c8655e;
color: #c8655e;
}
ip2region 数据库返回的原始格式为:
国家|省份|城市|ISP|ISO-Alpha2代码
示例:
| 原始字符串 | 国家 | 省份 | 城市 | ISP | ISO |
|---|---|---|---|---|---|
中国|广东省|深圳市|电信|CN | 中国 | 广东省 | 深圳市 | 电信 | CN |
美国|加利福尼亚州|洛杉矶|Google|US | 美国 | 加利福尼亚州 | 洛杉矶 | US | |
中国|0|0|联通|CN | 中国 | — | — | 联通 | CN |
当某字段数据为
0时,代表该数据库中无此字段记录。插件会自动过滤值为0的字段,不参与显示。
用户访问页面
│
├─ 前台评论显示
│ └─ get_comment_author 过滤器触发
│ └─ 读取评论 IP → 自动判断 IPv4/v6
│ └─ 加载对应 .xdb 数据库(向量索引缓存)
│ └─ 二分查找定位 → 解析归属地字段
│ └─ 按配置格式化 → 输出 HTML
│
└─ 文章发布者定位
└─ save_post 钩子触发(首次发布时)
└─ 获取发布者 IP
└─ 查询归属地 → 写入 post_meta
└─ 写入文章标签(📍前缀)
└─ 前台读取 post_meta 缓存展示
插件提供两种查询模式,由「内存缓存加速」开关控制:
| 模式 | 内存占用 | 磁盘 IO | 说明 |
|---|---|---|---|
| 向量索引缓存(推荐) | ~512 KB | 少量 | 将向量索引层加载到内存,大幅减少随机 IO |
| 文件读取模式 | 极少 | 较多 | 每次查询直接 fseek+fread,适合内存极度紧张的环境 |
两个 .xdb 文件缺一不可:ip2region_v4.xdb 用于 IPv4 查询,ip2region_v6.xdb 用于 IPv6 查询。激活后请在后台设置页确认数据库状态为「✓ 正常」。
文件权限:确保 Web 服务器用户(如 www-data)对两个 .xdb 文件有读取权限(chmod 644)。
主题调用安全:在主题模板中调用插件函数时,务必使用 function_exists() 判断,防止插件未启用时主题报错:
if ( function_exists( 'the_Yue_location' ) ) {
the_Yue_location( get_comment_author_IP() );
}
建议使用子主题:修改主题模板文件前,请先备份,建议在子主题中进行定制。
归属地精度:数据精度取决于 ip2region 数据库的收录情况,部分 IP 段可能仅有国家或省份信息,城市字段为空属正常现象。
IPv6 支持:IPv6 归属地数据覆盖范围相对 IPv4 略少,部分 IPv6 地址可能仅返回国家信息。
反向代理环境:如站点使用了 Nginx 反向代理或 CDN,评论者 IP 可能为代理服务器 IP,建议在服务器配置中正确透传 X-Forwarded-For 头。文章发布者 IP 获取顺序为:HTTP_X_FORWARDED_FOR → HTTP_CLIENT_IP → REMOTE_ADDR。
Q:激活后后台提示数据库文件缺失怎么办?
A:请确认插件目录下存在 ip2region_v4.xdb 和 ip2region_v6.xdb 两个文件,且服务器用户有读取权限。可通过 FTP 或 SSH 重新上传。
Q:前台评论没有显示归属地?
A:检查以下几点:① 后台「功能开关」中「前台评论自动显示」是否开启;② 数据库文件是否正常;③ 主题的评论模板是否使用了 get_comment_author 过滤器(部分主题可能绕过此过滤器)。
Q:主题评论模板不走 get_comment_author 过滤器怎么办?
A:关闭自动显示,改为在主题模板中手动调用 the_Yue_location( get_comment_author_IP() ) 函数。
Q:文章发布者定位功能开启后没有显示归属地?
A:该功能仅在文章首次发布时记录。如果文章已经发布过,需要删除对应的 _Yue_location_data post_meta 记录后重新发布,或手动写入数据。
Q:归属地显示"未知"?
A:表示该 IP 在数据库中未查到有效记录,或查到的所有字段均为 0。这是数据库覆盖率问题,属正常现象。
Q:可以同时在前台显示和后台评论列表显示吗?
A:可以,两个开关相互独立,可同时开启。
Yue_get_post_location() 和 the_Yue_post_location() 全局函数本插件以 GPL v2 or later 协议发布。
IP 归属地数据来源:ip2region — 开源离线 IP 归属地查询库,协议为 Apache 2.0。