log::error()写不进文件主因是php底层配置未启用、thinkphp日志通道未正确配置或app_debug=true绕过日志流程;需检查php.ini的log_errors、error_reporting、error_log,以及config/log.php的default驱动、level级别、runtime目录权限和app_debug=false开关。

Log::error() 写不进文件?不是代码错了,是配置没对上,或者环境根本没走日志流程。
PHP底层错误日志必须先开好
ThinkPHP 的日志系统只管「框架内抛出的异常」,而Fatal error、Parse error 这类 PHP 致命错误,连框架启动都过不去,压根不会进 Log::error()。它们靠的是 PHP 自身的 log_errors 和 error_log。
确保这三项在 php.ini 里已生效:
log_errors = On-
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED(生产环境推荐) -
error_log = /var/log/php_errors.log(路径不能是 web 可访问目录,且www-data或对应用户要有写权)
改完别忘了重启 PHP-FPM 或 Apache。测试是否生效:执行 php -r "error_log('test from php.ini', 0);",再看日志文件有没有新增内容。
ThinkPHP 6+ 的 config/log.php 关键项
ThinkPHP 6+ 日志配置集中在config/log.php,不是 app.php 或中间件里。它不控制 PHP 底层错误,但决定「框架异常」和 Log::xxx() 调用能否落地。
必须核对这几处:
-
'default' => 'file':驱动名必须是file,不是空字符串或test -
'channels' => ['file' => [...]]里的'level' => ['error', 'critical', 'alert', 'emergency']:只允许这些级别写入,info或debug在生产环境默认被过滤 -
'ignore_404' => false:设为true会跳过所有 404,线上排查路由问题时容易漏掉线索 -
'close' => false:千万别设成true,否则整个日志通道静默关闭,无任何提示
如果想固定日志文件名(比如总叫 error.log 方便监控),把 'file' => 'log/error.log' 写进 channels.file 配置里——注意这是相对于 runtime/ 的路径。
APP_DEBUG=false 是 error_log 生效的前提
开发时APP_DEBUG=true,错误直接打屏,Log::error() 和异常处理器都绕过了;只有 APP_DEBUG=false 时,未捕获异常才会走到 app/exception/Handle.php 的 report() 方法,并触发日志写入。
检查你的 .env:
-
APP_DEBUG=false(线上必须) -
APP_ENV=production(影响部分组件行为)
同时确认 config/exception.php 中 'log' => true 已开启——它控制「未被捕获的异常」是否写日志,和 Log::error() 是两套路径。
runtime/log/ 目录权限和文件名陷阱
ThinkPHP 默认往runtime/log/ 写,但两个坑最常导致「日志没生成却没报错」:
现象:file_put_contents(runtime/log/20240512.log): failed to open stream: No such file or directory
- 目录不存在或无写权限:部署后手动创建
runtime/log/,并执行chmod -R 755 runtime/(Linux)或确保 IIS/Apache 用户有写权(Windows) - 日期文件名干扰排查:默认按天分文件(如
20260424.log),但你查问题时可能下意识翻error.log。要么用'single' => true强制单文件,要么加个软链ln -sf 20260424.log latest.log
别在 file 路径里写 date('Ym') 这种动态目录——ThinkPHP 不自动创建多级目录,会静默失败,日志直接丢弃。
真正卡住人的,往往不是「怎么配」,而是「配了但没生效」——因为 PHP 底层日志、框架日志、环境开关三者没对齐,又没有明确报错提示。每次改完,记得用 php think clear:log 清缓存,再用 trigger_error('test', E_USER_ERROR) 或故意写个语法错误测一遍。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











