post-install-cmd仅在真正安装依赖时触发,如首次克隆、删lock后重装或lock与composer.json冲突需重建;vendor存在且lock未变则跳过,不执行。

composer run-script post-install-cmd 不是“手动触发安装后脚本”的正确方式——它只是执行一个叫 post-install-cmd 的自定义脚本,而这个脚本名恰好和 Composer 内置事件同名。真想验证钩子逻辑是否生效,得先确认它是不是被自动触发了,而不是靠 run-script 伪装。
为什么 composer run-script post-install-cmd 能跑通但没意义
你写的 "post-install-cmd": "php artisan cache:clear" 是个合法的脚本定义,composer run-script post-install-cmd 当然能执行它——但它和 Composer 安装流程完全无关,只是把字符串当命令跑了一遍。
- 这相当于你手动敲
php artisan cache:clear,跟“安装后”毫无关系 - 它不会加载 Composer 的上下文(比如当前安装的包列表、vendor 路径变更通知)
- 如果脚本里用了
$COMPOSER_EVENT或$COMPOSER_HOME这类环境变量,run-script模式下它们可能为空或不准确 - CI 环境里常禁用脚本(
--no-scripts),但run-script不受此影响,容易掩盖真实问题
post-install-cmd 实际触发条件有哪些
它只在 Composer 真正“安装依赖”时才跑,不是每次 composer install 都会进。常见满足条件的场景:
- 首次克隆项目,
composer.lock不存在 -
vendor/目录被删,且composer.lock存在但与composer.json中的require不匹配(比如你改了 PHP 版本约束或加了个新包,却没更新 lock) - 运行
composer install --force-reinstall(强制重装)
不触发的情况更常见:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
vendor/和composer.lock都存在且一致 → Composer 直接跳过安装,post-install-cmd静默不执行 - CI 流程中默认加了
--no-scripts(如 GitHub Actions 的php-actions/composer) - 脚本名写成
postInstallCmd或post_install_cmd→ Composer 完全无视
想每次 composer install 都执行,该换哪个钩子
别硬扛 post-install-cmd,它设计上就不是为“每次运行都执行”服务的。更可靠的选择是:
-
post-autoload-dump:只要vendor/autoload.php被重写就触发,包括install、update、dump-autoload。适合清缓存、生成代理类、扫描注解 -
post-update-cmd:所有composer update、composer require、composer install --with-dependencies都会走它。日常开发加包、升版更贴近“依赖变更后”语义 - 如果必须绑定到
install命令且每次都要跑,建议在 CI 脚本里显式追加命令,比如:composer install && php artisan cache:clear
调试时最容易忽略的三个点
脚本写对了、名字拼对了、命令也合法,但还是不执行?先查这几个地方:
-
composer install --verbose输出里有没有Executing script ...行?没有说明根本没走到钩子阶段 - 运行
composer show --scripts,确认post-install-cmd出现在“Event scripts”区块里,而不是混在普通脚本列表中 - 检查
composer.json顶层scripts字段是否为对象(JSON object),不是字符串;PHP 5.6+ 强制要求值是数组或对象,单字符串会被忽略
钩子行为高度依赖 Composer 对当前 vendor 和 lock 状态的判断,而不是你的主观预期。盯着实际文件状态比反复改脚本更有效。










