Composer插件必须实现PluginInterface接口并正确定义activate、deactivate、uninstall方法,通过autoload和extra.class正确配置类路径,监听官方事件而非手动hook,调试需强制重装并用writeError输出日志。

Composer 插件不是靠 composer.json 里写个 “type”: “composer-plugin” 就能跑起来的——它必须实现特定接口、注册事件监听器,并在正确时机被加载,否则 composer install 会静默忽略或直接报错。
插件类必须实现 ComposerPluginPluginInterface
这是硬性门槛。Composer 启动时只认这个接口,不实现就等于没写插件。
- 必须定义
activate()方法:接收$composer(ComposerComposer实例)和$io(ComposerIOIOInterface),这是你挂载逻辑的唯一入口 - 必须定义
deactivate()和uninstall(),哪怕空着——少一个就会触发Class does not implement ComposerPluginPluginInterface - 类不能是匿名类,不能用
final修饰(Composer 会尝试继承或代理)
composer.json 中的 autoload 和 extra 配置决定能否被识别
Composer 不按命名空间扫描插件,而是依赖自动加载 + 显式声明。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
"autoload": { "psr-4": { "MyPlugin\": "src/" } }—— 确保类能被 Composer 自动加载,路径写错会导致Class 'MyPluginPlugin' not found -
"extra": { "class": "MyPlugin\Plugin" }—— 必须指定主插件类全名,且该类必须可实例化(无构造参数,或参数有默认值) - 如果插件同时作为包发布,
"type": "composer-plugin"要写对,否则require进项目后不会被当作插件启用
监听事件要用 EventDispatcher,别直接改 $composer 对象
想在 post-install-cmd 或 pre-autoload-dump 时执行逻辑?不能靠手动 hook 命令,得走 Composer 官方事件流。
- 在
activate()里调用$composer->getEventDispatcher()->addListener('post-autoload-dump', [$this, 'onPostAutoloadDump']) - 事件名必须精确匹配文档列表(如
pre-install-cmd≠pre-install),拼错不会报错,但事件永远不会触发 - 回调方法接收
ComposerEventDispatcherEvent子类实例(如CommandEvent、PackageEvent),从中取上下文,而不是试图从$composer里“猜”当前状态
调试插件最有效的办法是加 echo + 强制重装
Composer 缓存插件加载结果,改了代码不重装就不会生效,日志也不输出。
- 每次修改后运行:
composer global remove vendor/plugin-name && composer global require ./path/to/plugin(本地开发时用pathrepo 更稳) - 在插件方法开头加
$io->writeError('<info>[DEBUG]</info> activate called');,用writeError才能在任何 verbosity 下看到 - 遇到
PluginManager::createPlugins() returned no plugins,90% 是extra.class指向的类不存在,或autoload路径没覆盖到
真正卡住的地方往往不是逻辑,而是 Composer 加载机制本身:类存在但没被自动加载,extra.class 写错大小写,事件名少个连字符——这些细节不打日志、不抛异常,只让插件彻底消失。

















