thinkphp日志写入需配置、通道、权限和生命周期四者协同;生产环境须关闭app_debug并显式配置log.level;通道名须严格匹配;路径须绝对且可写;cli需手动调用log::save()或直连file驱动。

ThinkPHP 文件日志写入不是调用一下 Log::info() 就自动落盘的事。它依赖配置、通道、权限和生命周期三者配合,缺一不可。默认情况下,很多写法看似执行了,但文件里空空如也——这不是 Bug,是设计逻辑。
确认日志是否真正“开启”
生产环境(APP_DEBUG = false)下,ThinkPHP 默认不记录任何日志,哪怕目录可写、配置存在。必须显式启用:
- 在
config/app.php中确保'log' => ['level' => ['info', 'error']]已配置(不能只写type) - 检查
config/log.php的'level'是字符串数组(如['info', 'error']),不是逗号字符串('info,error'会被忽略) - 若用环境变量控制,需在
public/index.php加载框架前定义LOG_LEVEL
指定有效通道并匹配配置键名
Log::info() 默认走 default 通道,但该通道必须在 config/log.php 中正确定义且启用:
- 配置中
'default' => 'file',则'file'键必须存在且'type' => 'File'(注意首字母大写) - 自定义通道如
'custom',代码必须写Log::channel('custom')->info(...),名称大小写、拼写必须与配置项完全一致 - 常见错误:配置里写
'Custom',代码却调用Log::channel('custom'),导致静默失败
确保路径可写且为绝对路径
相对路径 runtime/log/ 在 CLI、Swoole、FPM 等不同运行模式下解析基准不同,极易写错位置或失败:
- 在
config/log.php中将'path'改为绝对路径:'path' => realpath(__DIR__ . '/../runtime/log/') . DS, - 检查整个路径链上每一级目录(如
/var/www/app→runtime→log)都具备755权限,并归属 PHP 进程用户(如www-data或nginx) - Docker 环境需同步容器内外 UID/GID,仅
chown无效
手动触发保存或绕过门面直写
Web 请求结束时框架自动调用 Log::save(),但 CLI 命令、异步任务或异常中断时不会执行,日志滞留内存:
- CLI 场景(如定时任务)务必在逻辑末尾加
Log::save();更稳妥写法:try { /* 业务逻辑 */ } finally { Log::save(); } - 关键路径(支付回调、短信发送)推荐绕过门面,直接实例化驱动:
use think\log\driver\File;<br>$log = new File(['path' => runtime_path('log/sms/'), 'file' => 'sms.log']);<br>$log->info('发送成功', ['phone' => '138****']);
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











