自定义脚本须定义在 composer.json 的 scripts 键下,支持字符串命令、数组多命令、php 回调三种写法;回调需 public static 且类已 autoload;可通过 composer_dev_mode 等环境变量适配 --no-dev;优先用 post-autoload-dump 处理加载相关逻辑;php 回调可类型提示获取 $composer 和 $io 对象。

composer.json 里 scripts 字段怎么写
自定义脚本命令必须定义在 composer.json 的 scripts 键下,结构是键值对:键是命令名(比如 dev:clear-cache),值是具体要执行的命令或 PHP 回调。
支持三种写法:
- 字符串命令,如
"php artisan clear-compiled"(会交给 shell 执行) - 数组形式,支持多个命令顺序执行,如
["@php -v", "echo 'done'"] - PHP 回调,格式为
"MyScriptClass::myMethod"或"MyScriptClass::class"(需确保类已自动加载)
注意:回调方式要求类和方法是 public static,且不能依赖未加载的命名空间——常见错误是类没加 autoload 配置,运行时报 Class 'MyScriptClass' not found。
如何让自定义命令支持 --no-dev 或 --quiet 参数
Composer 脚本本身不解析这些参数,但你可以通过环境变量或手动判断来适配。例如,COMPOSER_DEV_MODE 环境变量在 --no-dev 时为 0,默认为 1;COMPOSER_NO_INTERACTION 对应 --no-interaction。
实操建议:
- 在 PHP 回调中用
getenv('COMPOSER_DEV_MODE') === '0'判断是否跳过 dev 相关逻辑 - 避免在脚本里硬编码
phpunit这类仅 dev 下存在的命令,否则--no-dev安装时会报sh: phpunit: not found - 使用
$_SERVER['argv']获取原始参数不推荐——Composer 会过滤掉大部分传入参数,不可靠
为什么 post-install-cmd 不触发,或者触发两次
这是 Composer 版本和事件绑定方式混用导致的典型问题。从 Composer 2.2 开始,post-install-cmd 和 post-update-cmd 默认只在对应命令显式执行时触发(如 composer install),而不会在 composer update 中触发前者。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
常见误配:
- 把需要每次更新都跑的逻辑(如生成 autoload 文件)错放在
post-install-cmd,结果composer update后失效 - 同时配置了
post-install-cmd和post-autoload-dump,又在脚本里重复执行 dump,造成冗余 - 使用
composer require xxx时,它本质是update流程,所以只触发post-update-cmd,不是post-install-cmd
建议优先用 post-autoload-dump 处理与自动加载相关的操作,它更精准、更可靠。
PHP 回调脚本里如何访问 Composer 实例和 IO 对象
如果脚本需要读取当前项目配置、包列表或输出带样式的提示,可以直接声明类型提示获取依赖对象:
public static function myCommand(\Composer\Composer $composer, \Composer\IO\IOInterface $io)
{
$io->write("Installing for " . $composer->getPackage()->getName());
$io->writeError("This goes to stderr"); // 避免被管道截断
}
关键点:
- 参数顺序固定:
Composer实例在前,IOInterface在后,不能颠倒 - 只有 CLI 模式下才会有完整 IO 对象;在非交互环境(如 CI)中
$io->isInteractive()返回 false - 不要在回调里调用
exit()或die(),会导致 Composer 进程异常终止,改用抛出\Exception
真正难调试的是跨平台路径处理和 autoload 加载时机——类文件必须在 composer dump-autoload 后才能被识别,否则脚本注册成功但运行时报错,这个延迟容易被忽略。










