scripts 字段必须置于 composer.json 根对象的顶层 "scripts" 键下,嵌套在 extra 或 config 中将被忽略;钩子名须严格匹配内置事件(如 post-update-cmd),大小写和连字符错误会导致静默跳过;推荐用数组定义命令以确保跨平台可靠性。

scripts 字段必须写在 composer.json 根对象里,不是嵌套在 config 或 extra 下;钩子名拼错、大小写/连字符不匹配、执行路径或环境变量没处理好,脚本就根本不会运行——而且 Composer 从不报错提示。
scripts 必须放在根 composer.json 的顶层 "scripts" 键下
它不是配置项,是 Composer 识别生命周期钩子的唯一入口。任何嵌套(比如塞进 extra.scripts 或 config.scripts)都会被完全忽略。
- ✅ 正确位置:
"scripts": { "post-install-cmd": "php artisan optimize:clear" } - ❌ 错误位置:
"extra": { "scripts": { "post-install-cmd": "..." } }—— 这个对象会被当成普通元数据,不触发任何脚本 - 脚本名必须是字符串字面量,不能是变量、模板或带空格的 key,比如
"post install-cmd"或"post-install cmd"都无效
钩子名大小写和连字符必须严格匹配内置事件名
Composer 不做模糊匹配,也不提示拼写错误,写错就静默跳过。你看到脚本“没执行”,90% 是因为名字不对。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- ✅ 正确事件名:
pre-install-cmd、post-update-cmd、pre-autoload-dump、post-autoload-dump - ❌ 常见错误:
post-autoloader-dump(多了一个r)、post-dump-autoload(顺序反了)、postinstall-cmd(缺连字符) - 自定义脚本名(如
ci:test)可以任意,但调用时必须和composer run-script后的参数完全一致:composer run-script ci:test
命令值用数组比字符串更可靠
字符串格式容易因 shell 解析失败(空格、引号嵌套、特殊字符),尤其在 Windows 或 CI 环境下。数组由 Composer 直接 exec,不经过 shell,参数传递干净。
- ✅ 推荐写法:
"post-update-cmd": ["php", "artisan", "cache:clear"] - ✅ 支持 PHP 回调:
"post-autoload-dump": ["MyClass::onDump"](类必须能被当前 autoloader 加载) - ✅ 支持递归调用其他脚本:
"@php -v"中的@会触发php脚本定义(如果存在) - ❌ 避免 shell 逻辑:
"if [ -f .env ]; then php artisan key:generate; fi"—— Windows 下直接崩溃,且无法跨平台
路径、PHP 二进制和环境变量不能依赖默认行为
Composer 执行脚本时工作目录是项目根目录,但 PATH 不一定包含 vendor/bin,.env 不会自动加载,$_ENV 也不一定有你想要的值。
- 用
vendor/bin/phpunit而不是phpunit,避免全局命令干扰或缺失 - 显式调用 PHP:
"php ./scripts/deploy.php",不要依赖 shebang 或可执行权限 - 需要读取
.env?得在 PHP 脚本里自己putenv()或require,别指望 Composer 自动处理 - CI 环境中,
.git目录可能不存在(shallow clone、deploy 模式),所以别在post-install-cmd里硬拷贝 hook 到.git/hooks/
最常被忽略的一点:post-install-cmd 只在首次 composer install(vendor/ 为空)时触发,而 post-update-cmd 才会在每次 composer update 或 lock 文件变更后的 install 中执行——如果你以为“安装后”就该走 post-install-cmd,大概率会漏掉关键动作。










