在登录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语句。