scripts字段必须位于composer.json根层级,不可嵌套在extra、config等子字段中;键名须严格匹配官方事件名,值支持字符串、数组或php静态方法,且仅根目录composer.json中的scripts生效。

scripts 字段必须写在根 composer.json 顶层,否则完全不生效。 它不是配置项、不是插件扩展、也不是 extra 或 config 的子字段——放错位置,脚本就等于没写。
scripts 字段必须在根 composer.json 顶层
常见错误是把它塞进 extra、config 或某个包的子配置里。Composer 只扫描项目根目录下 composer.json 的顶层 "scripts" 键:
- ✅ 正确:
"scripts": { "post-install-cmd": "php artisan optimize:clear" } - ❌ 错误:
"extra": { "scripts": { ... } }—— 静默忽略 - ❌ 错误:在 vendor/ 下某依赖包的
composer.json里写 scripts —— 根本不读
验证方式很简单:composer run-script --list 输出里看不到你的脚本名,基本就是位置错了。用 composer validate 也能发现格式是否合法,但它不会报“scripts 不在顶层”这种语义错误。
内置事件名拼写必须严格匹配,大小写和连字符都不能错
Composer 不校验钩子名是否有效,拼错就直接跳过,且不提示。比如:
-
post-autoload-dump✅(正确) -
post-autoloader-dump❌(多一个r,不触发) -
PostAutoloadDump❌(驼峰,不识别) -
post_dump_autoload❌(下划线,非标准分隔符)
真正会被自动调用的事件名只有官方文档列出的那十几个,例如:pre-install-cmd、post-update-cmd、post-root-package-install。别自己造名字指望它“意会”——after-install、onRequire 这类写法永远不执行。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
命令值支持字符串、数组、PHP 类方法,但行为差异很大
同一个钩子名,不同写法执行逻辑完全不同:
- 字符串:
"post-install-cmd": "php artisan key:generate"—— 交给 shell 解析,引号、空格、转义全得自己处理,Windows 下容易崩 - 数组:
"post-install-cmd": ["php", "artisan", "key:generate"]—— Composer 直接 exec,绕过 shell,更安全、跨平台兼容性好 - PHP 方法:
"post-autoload-dump": "MyBuild\Scripts::clearCache"—— 要求类已能被 autoload 加载(推荐放autoload-dev里),方法必须是public static,且签名可选接收ComposerScriptEvent对象
注意:数组形式里不能写 @xxx 别名(那是字符串命令里的语法),也不能带 && 或 || —— 数组每项独立执行,失败即中断。
@ 符号只在字符串命令中生效,用于递归调用其他 script
想复用已有脚本,得用 @ 前缀,但它只在字符串值里解析:
- ✅ 有效:
"test": "@clean && phpunit"→ 先展开@clean成实际命令,再交给 shell 执行 - ❌ 无效:
"test": ["@clean", "phpunit"]→ Composer 会尝试执行名为@clean的命令,报command not found - ❌ 无效:
"test": "clean && phpunit"→ shell 找不到clean命令,因为clean是你定义的 script 名,不是系统命令
@ 展开是 Composer 内部机制,不经过 shell,所以能跨平台;但嵌套太深(比如 @a 调 @b 再调 @c)容易出错,建议控制在两层内。
最常被忽略的一点:脚本是否执行,和 composer install 是否真的做了事强相关。如果 vendor/ 已存在、composer.lock 没变,Composer 可能跳过安装流程,也就不会触发 post-install-cmd —— 这时候加 -v 看日志,你会发现根本没 “Executing script” 这行输出。










