在登录 DouPHP 后台时,发现管理员登录记录 IP 地址总显示 127.0.0.1,以为是使用了 WAF 导致,在修改 CDN 回源绕过 WAF 后仍然如此。通过查看代码后发现 DouPHP 对获取到的 IP 地址只要不符合 IPv4 的正则表达式就返回 127.0.0.1 。 IPv6 已经成为网络通信的主流标准,官方至今 (DouPHP 版本 v1.8 Release 20250217) 仍未进行适配,为了正确显示 IPv6,需要自行修改以适配。
在 include/common.class.php 修改 get_ip() 方法以修正正则表达式:确保正则表达式能够匹配完整的 IPv6 地址,修改后代码如下。
function get_ip() {
static $ip;
if (isset($_SERVER)) {
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
// 处理 HTTP_X_FORWARDED_FOR 中可能包含的多个 IP 地址
$ip_list = explode(',', $_SERVER["HTTP_X_FORWARDED_FOR"]);
$ip = trim($ip_list[0]); // 取第一个 IP 地址
} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
$ip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$ip = $_SERVER["REMOTE_ADDR"];
}
} else {
if (getenv("HTTP_X_FORWARDED_FOR")) {
$ip_list = explode(',', getenv("HTTP_X_FORWARDED_FOR"));
$ip = trim($ip_list[0]); // 取第一个 IP 地址
} else if (getenv("HTTP_CLIENT_IP")) {
$ip = getenv("HTTP_CLIENT_IP");
} else {
$ip = getenv("REMOTE_ADDR");
}
}
// 支持 IPv4 和 IPv6 的正则表达式
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
return $ip;
} else {
return '127.0.0.1'; // 默认返回本地回环地址
}
}
数据库中 IP 字段的类型为 VARCHAR(15),这是 IPv4 的长度限制,需要将其调整为支持 IPv6 的长度。 IPv6 地址最长为 39 个字符,因此将字段长度设置为 VARCHAR(39) 或更高。可手动修改或执行以下 sql 语句:
-- 管理员登录记录中的 IP
ALTER TABLE `dou_admin_log` MODIFY COLUMN `ip` VARCHAR(40);
-- 插件智能客服对话记录中的首次访问 IP 和最近访问 IP
ALTER TABLE `dou_chat_service` MODIFY COLUMN `first_ip` VARCHAR(40);
ALTER TABLE `dou_chat_service` MODIFY COLUMN `last_ip` VARCHAR(40);
-- 插件智能客服对话记录的每条对话记录 IP(虽然后台没有显示,但在数据库中有该字段)
ALTER TABLE `dou_chat_service_recorde` MODIFY COLUMN `ip` VARCHAR(40);
如果没有安装插件智能客服,只需要修改或执行第一个 sql 语句。