log::write() 默认不输出到控制台,仅写入文件;如需控制台显示,应配置 stdout channel 或直接使用 echo/dump。

Log::write() 写不到控制台?默认不输出到 stdout
ThinkPHP 的 Log::write() 默认只写入文件(如 runtime/log/ 下),不会打印到 PHP CLI 控制台。这不是 bug,是设计使然——日志系统面向生产环境持久化,而非调试实时反馈。
想在命令行运行时看到日志,得手动触发输出,或改用更轻量的调试方式:
- 开发阶段优先用
dump()或echo/var_dump(),直接刷屏,零配置 - 非要用
Log::write()且希望同时看控制台?得自己加一层转发逻辑,比如在AppService.php或命令类里 hook 日志写入 - 注意:CLI 模式下
Log::record()记录的日志仍只进文件,不自动同步到终端
log_level 配置对 console 输出无效
log_level(如 'log_level' => ['error', 'info'])只控制「哪些级别写入日志文件」,不影响是否显示在控制台。很多人调了这个发现 Log::write('debug', 'xxx') 还是看不见,其实是根本没走控制台路径。
真正决定能否“看见”的,是输出目标,不是级别过滤:
- 级别影响的是
Log::write()是否被记录进文件,debug级别在默认配置下通常被忽略(需显式开启) - 若想让
debug日志进文件,要确保log_type是File且log_level包含debug - 但即便进了文件,你也得
tail -f runtime/log/xxxx.log才能看到——这不算“控制台输出”
想真正在 console 打印日志?用 think\facade\Log::info() + 自定义 handler
ThinkPHP 6+ 支持日志 channel,可为 CLI 场景单独配一个输出到 stdout 的 channel。比改全局配置更干净,也避免污染 HTTP 请求日志。
在 config/log.php 中新增 channel:
'stdout' => [
'type' => 'console',
'level' => ['debug', 'info', 'notice', 'warning', 'error'],
],
然后在代码里指定 channel 调用:
think\facade\Log::channel('stdout')->info('这是控制台可见的日志');- 注意:
console类型 handler 在 ThinkPHP 6.0.10+ 才稳定支持;低版本会报class not found: think\log\driver\Console - 如果用的是 TP5.x,没有原生
consoledriver,只能自己写个简单输出类,write()方法里直接echo date('[c]')." {$level}: {$message}\n"
Log::debug() 不生效?检查 debug 模式和 level 白名单
Log::debug('msg') 在 TP6 中本质是 Log::write('debug', 'msg'),但它受两重限制:应用是否开启 app_debug = true,以及当前 channel 的 level 是否包含 debug。
常见失效场景:
- 部署环境
app_debug = false→ 所有debug级日志被静默丢弃,连文件都不写 - channel 配置里
level是['error', 'warning']→debug被过滤,即使app_debug = true也没用 - TP5 中
Log::debug()是别名,实际调用Log::record(),而record()默认不写文件,只存内存,需手动Log::save()才落地
最省事的调试法:CLI 下直接 echo "DEBUG: ".json_encode($data)."\n";,不依赖框架日志链路,也不怕配置漏掉哪一环。
日志通道、级别、输出目标三者容易混为一谈,但它们各自管一段:app_debug 开关底层记录资格,level 决定通道内过滤,type 才决定最终去哪——控制台只是其中一个可能的终点,不是默认终点。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










