You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义PHP日志功能出现重复日志条目问题排查求助

问题成因

日志重复写入的核心原因是**controller.php被执行了两次**,触发源是.htaccess配置结合浏览器的默认行为:

  1. 访问站点根目录时,服务器通过DirectoryIndex controller.php加载controller.php,执行日志写入逻辑;
  2. 浏览器会自动请求站点的favicon.ico(网站图标),该文件不存在时,你的Rewrite规则会将这个请求转发到controller.php,导致脚本被第二次执行。由于两次请求间隔极短,时间戳完全一致,最终生成重复日志。

你可以在controller.php开头添加var_dump($_SERVER['REQUEST_URI']);验证,会看到两次请求的URI分别是/和/favicon.ico。

修复方法

推荐以下几种解决方案,按优先级排序:

方案1:添加真实的favicon.ico文件

直接在站点根目录放置一个favicon.ico文件,浏览器会请求这个真实存在的资源,不会触发Rewrite规则转发到controller.php。

方案2:修改.htaccess,排除静态资源的Rewrite

在原有Rewrite规则前添加一条规则,跳过对favicon.ico的转发处理:

# 跳过favicon.ico的Rewrite规则
RewriteRule ^favicon.ico$ - [L]

# 原有的Rewrite规则
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ controller.php?page=$1 [QSA,NC,L]

-[L]表示不对该请求应用后续Rewrite规则,直接返回原资源(不存在则返回404),不会转发到controller.php。

方案3:在controller.php中过滤非页面请求

在controller.php的最开头添加判断,直接退出静态资源请求的处理:

// 过滤favicon.ico等非业务请求
if ($_SERVER['REQUEST_URI'] === '/favicon.ico') {
    exit;
}

这样即使请求被转发到controller.php,也会直接终止执行,不会触发日志写入逻辑。

额外优化建议

  1. 你的Report::notice方法返回类型是void,但controller.php中用了if(Report::notice(...))判断,这在PHP中会因为void返回null导致条件永远为false,可以修改notice方法返回write的结果:
public static function notice(string $message): bool {
    return Report::write('notice', $message, 'notice');
}
  1. 日志写入时建议增加文件锁,避免并发场景下的日志错乱:
// 替换原有的file_put_contents逻辑
$handle = fopen($file, 'a');
if ($handle) {
    flock($handle, LOCK_EX); // 独占锁
    fwrite($handle, $message . PHP_EOL);
    flock($handle, LOCK_UN); // 释放锁
    fclose($handle);
} else {
    return false;
}

内容的提问来源于stack exchange,提问作者Ere Männistö

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:35:16