跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

ThinkPHP8.0日志如何记录_ThinkPHP8.0日志配置与写入【调试】

ThinkPHP 8.0 日志默认不写入文件,需同时满足开启记录、配置有效通道、请求正常结束(或手动调用Log::save());仅调用Log::info()或Log::record()不会落盘。 ThinkPHP 8.0 的日志默认不写入文件,除非你显式开启记录、配置了有效通道,且请求正常结束(或手动触发
Log::save()
)。光靠
Log::info()
或
Log::record()
调用,日志只是暂存在内存里,不会落盘。 日志不写入文件的常见原因 最常踩的坑是:以为调用了就写了,结果 runtime/log/ 下空空如也。核心问题通常出在三处:
APP_DEBUG
为
false
时,
config/log.php
中的
'level'
若为空数组(
[]
),则所有级别日志都会被过滤掉 —— 这比
LOG_RECORD=>false
更隐蔽 未配置
'path'
,或路径不可写(如
runtime/log/
目录不存在、权限不足、父目录无执行权限) 使用了
Log::record()
但没调用
Log::save()
,或在 CLI 命令中未手动保存(Web 请求结束会自动 save,CLI 不会) 配置 log. php 时 level 和 channels 的关键写法 TP8 的日志配置以
config/log.php
为准,不再读取旧版
LOG_LEVEL
常量。正确写法必须明确指定级别数组和通道驱动:
'level'
必须是字符串数组,例如
['info', 'error', 'sql']
;写成
'INFO,ERROR'
字符串会被忽略
'channels'
中的
'file'
通道必须显式启用,且
'type'
值为
'File'
(首字母大写,小写
'file'
会静默失败) 若想把 SQL 单独记到
sql.log
,需额外定义一个
'sql'
通道,并在模型或 Db 类中用
Log::channel('sql')->info(...)
示例最小可用配置: 立即学习 “ PHP免费学习笔记(深入) ”; PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载
return [ 'default' => 'file', 'level' => ['info', 'error', 'sql'], 'channels' => [ 'file' => [ 'type' => 'File', 'path' => runtime_path('log/'), 'single' => false, 'max_files' => 30, ], ], ];
CLI 命令中写日志必须手动 save 在定时任务或自定义命令(如
php think demo:task
)中,
Log::info()
不会自动落盘。因为 CLI 没有“请求结束”生命周期钩子。 必须在命令逻辑末尾加
Log::save();
,否则日志永远留在内存 若命令中途异常退出(未捕获的 Exception),
Log::save()
不会执行,已 record 的内容丢失 建议包裹在
try...finally
中:
finally { Log::save(); }
,确保无论成功失败都写一次 调试时快速验证日志是否生效 别等部署后翻日志文件。本地调试可直接用以下两行代码验证通路: 先确认路径可写:
is_writable(runtime_path('log/'))
返回
true
再强制写一条并立即保存:
Log::channel('file')->info('test at '.date('Y-m-d H:i:s')); Log::save();
立刻检查
runtime/log/2026-05-08.log
是否新增一行 —— 注意日期文件名按天滚动,不是固定文件名 真正容易被忽略的是:日志通道名(
'file'
)、驱动类名(
'File'
)、级别写法(数组非字符串)、CLI 下的 save 时机 —— 这四点错一个,日志就静默消失。

相关文章