log_errors = off 是日志为空的主因,需显式设为 on 并确认生效;error_log 路径需存在且权限匹配运行用户,容器中推荐用 /dev/stderr;caddy 日志不包含 php 错误,二者需分别配置。

display_errors = Off 但 error_log 没内容?先确认 log_errors 是否真开启
关闭 display_errors 后看不到错误,不等于错误被丢弃——前提是 log_errors = On 必须同时生效。很多情况下日志为空,根本原因是这个开关被忽略或没生效:
-
log_errors默认值是Off(尤其在某些 FrankenPHP 内置 PHP 配置中),仅设error_log路径无效 - FrankenPHP 启动时若未加载自定义
php.ini,会 fallback 到编译时内置值,建议用frankenphp php-cli -i | grep log_errors查“Local Value”是否为On - 如果输出是
Off,必须显式配置:在php.ini中写log_errors = On,并确保 FrankenPHP 加载了它(可通过frankenphp php-cli -i | grep "Loaded Configuration File"确认路径)
error_log 路径写对了,但文件没生成或没写入?检查权限和路径有效性
error_log 设的是绝对路径,但 FrankenPHP 进程用户(如 www-data 或容器内非 root 用户)可能无权创建父目录或写入文件:
- 路径不能是
/var/log/php_errors.log却让进程去写/var/log/php/目录——要确保整个路径存在:sudo mkdir -p /var/log/php && sudo touch /var/log/php_errors.log - 用
ls -l /var/log/php_errors.log看属主是否匹配 FrankenPHP 运行用户(常见是www-data:www-data);否则执行sudo chown www-data:www-data /var/log/php_errors.log - 测试是否真正写入:在 PHP 脚本里加一行
trigger_error("test notice", E_USER_NOTICE);,再查日志文件是否有新增;没内容就说明配置或权限仍有问题
FrankenPHP 容器环境里 error_log 写到哪了?别只盯文件
在 Docker 中运行 FrankenPHP 时,error_log = /dev/stderr 反而是更可靠的选择——它绕过文件权限问题,把 PHP 错误直接推到容器 stdout:
- 修改
php.ini:设error_log = /dev/stderr,同时保持log_errors = On - 这样所有 PHP 错误(Warning、Fatal Error 等)都会混在
docker logs -f输出里,和 Caddy 访问日志、启动信息一起可见 - 注意:不要设成
error_log = stderr(少斜杠),Linux 下只有/dev/stderr是有效设备路径;设错会导致错误静默丢失 - 如果必须落盘,建议挂载宿主机目录(如
-v /host/logs:/var/log/php),并在容器内用绝对路径指向该位置
Caddy 日志和 PHP 日志是两套系统,别指望一个配置管全部
很多人以为配了 Caddy 的 { log } 就能看见 PHP 错误,其实完全不是一回事:
- Caddy
log块只记录 HTTP 层事件:请求路径、状态码、耗时、客户端 IP——它 不会 记录echo $undefined_var;这类 PHP Notice - PHP 错误日志由
php.ini中的log_errors+error_log控制,FrankenPHP 不干预也不合并这两者 - 调试时建议两边都开:Caddy 日志看“有没有请求进来”,PHP 错误日志看“脚本执行卡在哪”;比如 500 响应对应 Caddy 日志里有状态码,而 PHP 日志里会有具体 Fatal error 行号
log_errors 默认关着,且容器环境下 /dev/stderr 比文件路径更稳——别在没确认它是否开启前,就去翻日志文件。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











