Composer安装时日志目录不存在会导致写入失败并可能报错或静默丢弃日志;需通过post-install-cmd/post-update-cmd事件自动创建目录,推荐使用PHP脚本方式以确保跨平台兼容性、权限控制及环境变量支持。

Composer安装时日志目录不存在会怎样
默认情况下,composer install 或 composer update 不会自动创建日志路径——哪怕你在 phpunit.xml、monolog 配置或自定义脚本中指定了 logs/ 这类目录。一旦日志写入失败(比如 mkdir(): No such file or directory),应用可能直接报错或静默丢弃日志,排查起来非常被动。
用 Composer 的 post-install-cmd 和 post-update-cmd 自动建目录
最稳妥的做法是把目录创建逻辑交给 Composer 的脚本事件,在依赖装完后立即执行。这比靠应用启动时检测更可靠,也避免了首次请求才触发的延迟和权限问题。
- 在
composer.json的"scripts"段落里添加:
"scripts": {
"post-install-cmd": [
"mkdir -p var/logs",
"mkdir -p var/cache"
],
"post-update-cmd": [
"mkdir -p var/logs",
"mkdir -p var/cache"
]
}
注意:mkdir -p 是关键,它能递归创建父目录且不报错;Windows 用户需改用 PowerShell -Command "if (!(Test-Path 'var\\logs')) { New-Item -ItemType Directory -Path 'var\\logs' }",但更推荐统一用 symfony/console 类命令封装成 PHP 脚本,规避平台差异。
PHP 脚本方式更可控(尤其多环境或复杂路径)
当路径依赖环境变量(如 $_ENV['LOG_DIR'])或需设置权限时,shell 命令容易失控。此时写个简单 PHP 脚本更稳:
- 新建
bin/mkdirs.php:
<?php
$dirs = ['var/logs', 'var/cache', 'storage/logs'];
foreach ($dirs as $dir) {
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
- 在
composer.json中调用:
"post-install-cmd": [ "php bin/mkdirs.php" ]
这样能精确控制 umask、错误提示、跳过已存在目录,也方便后续加 chown 或 SELinux 上下文处理。
别漏掉 vendor/autoload.php 加载前的日志需求
有些项目在 autoload.php 加载阶段就要写日志(比如 autoloader 错误捕获),这时 post-install-cmd 已太晚。必须确保 composer install --no-autoloader 后手动补建,或把目录创建提前到 pre-install-cmd。但要注意:此时 vendor/ 可能还没解包,路径相对位置要算准,建议只建项目根目录下的固定路径(如 logs/),别依赖 vendor/ 内部结构。
真正麻烦的是 CI/CD 环境里多次并发运行 composer install ——mkdir -p 虽然幂等,但若多个进程同时判断+创建同一级目录,仍可能因竞态导致权限混乱。这时候得靠锁文件或统一由部署脚本前置处理,而不是全指望 Composer。


















