ThinkPHP6日志路径必须通过配置驱动控制:先用RUNTIME_PATH常量迁移runtime根目录出Web范围确保安全,再在config/log.php中配置channels.file.path指定日志子路径,最后清缓存、验证写入并排查权限与环境一致性。

ThinkPHP6 日志路径不能靠手动改文件夹位置来实现,必须通过配置驱动控制。核心是两层路径:一是整个 runtime 目录的位置,二是日志通道(channel)的具体子路径。改对了才稳定、安全、不丢日志。
一、优先移走 runtime 根目录(关键安全步骤)
默认 runtime/log/ 在 Web 可访问范围内,直接暴露日志等于泄露数据库密码、SQL 和用户 token。必须先把它整体迁出 Web 根目录。
- 在
public/index.php最顶部、require autoload.php之前,定义绝对路径常量:define('RUNTIME_PATH', '/data/www/myapp-runtime/'); - 确保该路径 PHP 进程有读写权限:
mkdir -p /data/www/myapp-runtime && chown -R www-data:www-data /data/www/myapp-runtime - 确认 Nginx/Apache 的
root指向的是public/,且/data/www/myapp-runtime不在其任何alias或子目录下
二、再配置日志通道的 path(精准定位 log 子目录)
即使 runtime 已移走,日志仍默认写入 runtime/log/。要自定义具体存放位置(比如分环境、分类型),需修改日志通道配置。
- 打开
config/log.php,找到'default'通道配置块 - 添加或修改
'path'项,值必须为绝对路径,末尾带斜杠:'path' => '/data/logs/myapp/', - 更推荐动态写法,避免硬编码:
'path' => env('LOG_PATH', runtime_path() . 'log' . DIRECTORY_SEPARATOR), - 若用多通道(如单独存 SQL 日志),每个通道可独立设
path,例如:'sql' => ['type' => 'File', 'path' => '/data/logs/sql/', 'level' => ['sql']]
三、改完必须做的三件事
配置不会自动生效,漏掉任一环节都可能导致日志“消失”。
立即学习“PHP免费学习笔记(深入)”;
- 清空缓存:
php think clear:log或手动删掉runtime/cache/下所有文件 - 触发一次日志写入(如在控制器里写
Log::info('test');),然后检查目标路径是否生成了新文件 - 验证配置是否加载成功:在代码中打印
Log::getChannel('default')->getConfig()['path'],看输出是否是你设的路径
四、常见问题排查点
如果日志还是没写进去,别急着重配,先看这几个地方:
- 目录权限是否完整?Linux 下每一级父目录(如
/data、/data/logs)都必须有x权限,否则 PHP 进不了路径 - CLI 和 Web 模式是否一致?命令行运行
php think时,可能读取的是config/console.php里的日志配置 - 是否用了 Swoole 或 think-swoole 扩展?这类扩展会接管日志驱动,需额外在扩展配置里指定
log.path - 是否误改了
think\log\driver\File类内部路径?这是硬编码,升级后会被覆盖,不可维护



















