脚本不执行主因是位置错误、钩子名拼错或触发时机混淆;scripts须在composer.json根层级,钩子名严格匹配大小写和连字符,推荐用数组格式并显式指定命令路径。

脚本不执行?90% 是因为位置写错、钩子名拼错,或根本没搞清触发时机。
scripts 必须放在 composer.json 根层级,嵌套在 extra 或 config 里等于没写
Composer 只扫描项目根目录下 composer.json 的顶层 "scripts" 键。任何嵌套都会被完全忽略,且不报错、不提示。
- ✅ 正确:
"scripts": { "post-update-cmd": "php artisan optimize:clear" } - ❌ 错误:
"extra": { "scripts": { "post-update-cmd": "..." } }→ 当成普通元数据,不触发 - ❌ 错误:在
vendor/下某个包的composer.json里写scripts→ Composer 根本不读 - 验证方式:运行
composer run-script --list,如果看不到你的脚本名,基本就是位置错了
钩子名大小写和连字符必须严格匹配,拼错一个字符就静默跳过
Composer 不做模糊匹配,也不校验事件名是否有效。写错就跳过,不会提醒你哪里不对。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- ✅ 正确:
pre-install-cmd、post-update-cmd、post-autoload-dump - ❌ 常见错误:
post-autoloader-dump(多一个 r)、postdump-autoload(顺序反)、post-install cmd(空格代替连字符)、PostInstallCmd(驼峰) - 自定义脚本名(如
ci:test)可任意,但调用时必须和composer run-script ci:test完全一致 - 注意:
post-create-project-cmd是真实存在的,但它只在composer create-project执行时、且由目标模板包自身声明才生效;你在本地项目里加了它,再跑install或update是不会触发的
用数组写命令比字符串更可靠,尤其在 CI 和 Windows 环境下
字符串格式依赖 shell 解析,容易因空格、引号、特殊字符或系统差异失败;数组由 Composer 直接 exec,参数传递干净,跨平台兼容性更好。
- ✅ 推荐:
"post-install-cmd": ["@php", "artisan", "key:generate"] - ❌ 风险高:
"post-install-cmd": "php artisan key:generate"→ Windows 下可能崩,含空格路径需手动转义 -
@php是 Composer 内置别名,自动匹配当前运行 Composer 的 PHP 可执行文件,避免版本错配 - 数组里不能用
&&、||或if条件判断——这些是 shell 语法,数组模式不经过 shell
触发时机决定行为逻辑,别把 post-install-cmd 当 post-update-cmd 用
这两个钩子看似相似,但触发条件完全不同,混用会导致“脚本有时跑、有时不跑”的困惑。
-
post-install-cmd:仅当vendor/为空或被清空后,运行composer install才触发;composer require或composer update不会触发它 -
post-update-cmd:每次composer update(无论是否带参数)都触发;也适用于已有依赖后再次运行composer install的场景 - CI 环境中常因缓存导致
vendor/未清空,post-install-cmd直接不跑;此时改用post-update-cmd更可靠 - 想“每次装/更都执行”,推荐统一指向自定义脚本:
"post-install-cmd": ["@build"]和"post-update-cmd": ["@build"]
最易被忽略的一点:脚本里调用的命令(比如 phpunit、artisan)默认不在 PATH 中,直接写会报 command not found;必须显式写 vendor/bin/phpunit 或用 @php + 路径,否则在不同环境大概率失败。










