Composer插件必须同时满足四项条件:声明"type": "composer-plugin"、配置"extra.class"指定全限定类名、设置autoload路径映射、在根composer.json中显式列入allow-plugins白名单,缺一不可。

能扩展,但不是靠“写个脚本扔进 bin/”就能用——必须走 Composer 插件机制,且从 Composer 2.2 开始,allow-plugins 还得手动放行,否则直接报错中断。
composer.json 必须同时满足 type + extra.class + autoload
Composer 不扫描文件、不猜类名,只认 composer.json 里这三项是否齐备:
-
"type": "composer-plugin"—— 缺了这一行,整个包被当普通库处理,PluginInterface再完整也白写 -
"extra": { "class": "MyVendor\MyPlugin\Plugin" }—— 类名必须带完整命名空间,不能漏双反斜杠,也不能写成MyPlugin.php或src/Plugin -
"autoload": { "psr-4": { "MyVendor\MyPlugin\": "src/" } }—— 路径映射必须让 Composer 能自动加载到那个实现PluginInterface的类;否则activate()根本不会被调用
常见现象:插件已 require,composer show 也能看到包,但 activate() 一丁点没执行。八成是 autoload 映射错位,或 extra.class 拼错了大小写。
自定义命令必须实现 CommandProviderInterface
光有插件类还不够,要让 composer my:command 可用,还得让插件“主动交出命令实例”:
- 插件主类必须
implements ComposerPluginCommandProviderInterface,否则 Composer 压根不调getCommands() -
getCommands()必须返回array,每个元素是继承自ComposerCommandBaseCommand的实例(不是SymfonyComponentConsoleCommandCommand) - 对应命令类里可用
$this->getComposer()拿项目实例,不用自己 new 或注入;重写initialize()手动 fetch 是多余的 - 插件的
composer.json还要加"extra": { "command-provider": "MyVendor\MyPlugin\CommandProvider" },值必须是全限定类名
错误示例:getCommands() 返回空数组、返回 new SymfonyComponentConsoleCommandCommand()、或 command-provider 写成 CommandProvider(缺命名空间)——结果都是 Command "my:command" is not defined,且无任何提示。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
Composer 2.2+ 必须显式允许插件运行
从 2.2 版本起,所有插件默认被禁用,composer install 会直接失败并抛出:
Plugin installation is disabled. You must allow the plugins you want to use in your composer.json.
解决方法只有两个地方可配:
- 项目级:在项目根目录
composer.json的**根级**加"allow-plugins": ["my-vendor/my-plugin"],注意是字符串数组,包名大小写敏感,不可通配 - 全局级(慎用):修改
~/.composer/config.json中的config.allow-plugins字段
别写 "allow-plugins": true,这等于关掉全部安全校验;也别漏掉你依赖的其他插件(比如 symfony/flex),否则 recipe 不生效,连 composer create-project 都可能卡住。
activate() 是唯一可信的执行入口
插件逻辑不能塞进 __construct(),也不能指望 composer require 后立刻生效——所有操作必须在 activate(Composer $composer, IOInterface $io) 里做:
- 监听事件要用
$composer->getEventDispatcher()->addListener('post-install-cmd', [$this, 'onPostInstall']),且回调方法签名必须接收具体子类,如CommandEvent $event - 注册命令、修改安装器、读取配置,都通过
$composer和$io实例完成,不要依赖getcwd()或全局路径 - 避免在
activate()里做网络请求或长耗时 I/O,CI 环境下容易超时静默失败 - 业务逻辑务必用
try/catch包裹,否则异常会中断整个composer install流程
最常被忽略的一点:插件类是否真被自动加载成功?composer dump-autoload -o 后再试,比反复改 activate() 更有效。

















