post-update-cmd 更可靠因其在 composer update 和 install --update 时均稳定执行,而 post-install-cmd 仅在 lock 文件缺失或过期时触发;配置多命令应优先用独立 PHP 脚本而非 JSON 数组,兼顾容错与可维护性。

post-update-cmd 为什么比 post-install-cmd 更可靠
因为 post-install-cmd 只在 composer.lock 不存在或已过期时触发,比如首次克隆项目、手动删了 lock 文件、或 composer.json 的 require 被修改后重装——它不是每次 composer install 都跑。而 post-update-cmd 在 composer update 和 composer install --update 时都会稳定执行,更适合部署中“每次依赖变更都要同步环境”的场景。
如何配置多命令顺序执行且容错
直接在 scripts 里写数组,每条命令独立运行,前一条失败默认不影响后续(除非 shell 层面用 && 连接)。但实际部署中更推荐显式控制流程:
- 用
@php -r内联脚本做条件判断,比如先检查artisan是否存在再调用:@php -r "file_exists('artisan') && exec('php artisan cache:clear');" - 把复杂逻辑抽到单独 PHP 文件(如
bin/post-update.php),避免 JSON 中转义和可读性问题 - Linux/macOS 下用
rm -f而非rm -rf清目录,防止误删上层结构;Windows 环境建议统一走 PHP 脚本,避开del/rd权限差异 - 所有涉及文件操作的命令,加上
|| true可屏蔽非关键错误(如清空一个不存在的缓存目录),但别滥用——关键步骤如chmod失败必须暴露
生产环境部署时 post-update-cmd 不执行?检查这三点
常见现象是本地 composer update 能清缓存,CI/CD 流水线里却静默跳过。原因通常是:
- CI 默认启用
--no-scripts(尤其在安全策略严格的平台),需显式加--no-dev --optimize-autoloader,但**不能漏掉--no-scripts=false或去掉该参数** -
post-update-cmd里的命令依赖 dev 包(如phpunit、infection),而部署时用了--no-dev导致命令找不到——应把真正需要的清理逻辑拆进不依赖 dev 工具的脚本,或改用composer run-script clear-cache --no-dev - 权限问题:脚本尝试
chmod storage但部署用户无权修改,报Operation not permitted;此时应提前用 root 或部署用户确保父目录可写,而不是靠脚本临时提权
跨框架/多环境的清理脚本怎么写才不耦合
硬编码 php artisan cache:clear 会让 Laravel 脚本在 Symfony 项目里失效。解法是分层抽象:
- 在
composer.json中只调用统一入口:"post-update-cmd": ["php bin/deploy-hook.php"] -
bin/deploy-hook.php里根据getenv('APP_ENV')或是否存在artisan/bin/console自动识别框架,再分发对应命令 - 缓存路径尽量用框架原生 API 获取(如 Laravel 的
app()->getCachedConfigPath()),而非拼接storage/framework/cache这类固定路径——后者在不同版本或自定义配置下可能失效
真正容易被忽略的是:这些脚本运行时的当前工作目录(CWD)是项目根目录,但某些命令(如前端构建产物清理)可能依赖相对路径,一旦 CI 使用了 --working-dir 或子模块部署,CWD 就会偏移。务必在脚本开头加 chdir(dirname(__DIR__)); 显式锚定,别信默认。











