thinkphp 6 错误日志写不进文件的主因是 app_debug = true 时框架跳过日志落盘,仅在 false 时通过 register_shutdown_function 捕获 fatal/parse error;需确保 .env 设 app_debug=false、log 配置中 default='file'、channels.file.level 为数组、close=false,并保证 runtime/log 目录存在且可写。

错误日志写不进文件?大概率不是配置漏了,而是 APP_DEBUG = true 时框架根本绕过日志落盘流程——它直接把错误打到页面上,error_log 和 runtime/log/ 都不会碰。
APP_DEBUG 关闭是日志落地的前提
ThinkPHP 6 的错误日志(尤其是 Fatal error、Parse error)依赖 register_shutdown_function 捕获,但这个机制只在 APP_DEBUG = false 时启用。开发时开着 debug,等于主动关掉了日志写入通道。
-
.env中必须设app_debug=false(线上环境强制要求) -
config/app.php里的'app_debug' => true会被.env覆盖,改这里没用 - 验证方式:临时加一行
echo config('app.app_debug') ? 'debug on' : 'debug off';,确认值为false
log.php 里真正起作用的三个关键项
很多人改了 'level' => ['error'] 还没日志,是因为只改了表面参数。下面这三项缺一不可:
-
'default' => 'file':确保默认通道是file,不是空字符串或test -
'channels' => ['file' => ['level' => ['error', 'warning']]]:注意这里是数组,不是字符串'error';单个字符串会失效 -
'close' => false(全局和 channel 里都要检查):设成true就等于手动关掉整个日志系统
别碰 'ignore_404' => false ——它只影响 404 是否进日志,跟致命错误无关。
runtime/log/ 目录权限和路径陷阱
最常见的报错是:file_put_contents(runtime/log/20240512.log): failed to open stream: No such file or directory。这不是配置问题,是路径没创建或没权限。
- 部署时必须手动执行:
mkdir -p runtime/log && chmod -R 755 runtime(Linux) -
'path' => '/data/logs/myapp'这种绝对路径要确保 PHP 进程用户(如 www-data)有写权,且目录存在 - 想固定日志文件名便于监控?改
'file' => 'log/error.log'(注意:这是相对于runtime/的路径,不是绝对路径) - 别用
'path' => 'log/' . date('Ym')—— ThinkPHP 不自动创建多级子目录,会静默失败
记录堆栈和捕获未 catch 异常
默认日志不带堆栈,查问题像蒙眼摸象。加这一项才有效:
-
'record_trace' => true放在channels.file配置块里,不是顶层 - 未被
try-catch捕获的异常,靠config/exception.php中的'log' => true控制是否写日志(默认是true,别动) - 别在
ExceptionHandle::render()里直接Log::error($e)——$e是对象,error_log写不进去,得用$e->getTraceAsString()或(string) $e
最易忽略的一点:Fatal error 类错误不会触发 Log::error() 调用,它们走的是 shutdown 函数 + error_get_last() 流程,所以 APP_DEBUG = false 和目录可写这两条,一条都不能少。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











