composer插件必须实现plugininterface接口且仅通过activate()入口获取$composer和$io,事件监听需用eventsubscriberinterface及静态getsubscribedevents()方法,严格区分事件名大小写与触发时机。

Composer 插件不是靠“注册函数”或“继承基类”就能生效的——它依赖明确的事件生命周期和 PluginInterface 实现,漏掉任意一个钩子点或事件监听时机,插件就完全静默。
Composer 插件必须实现 PluginInterface 才能被加载
Composer 不会扫描任意类,只认 Composer\Plugin\PluginInterface。只要你的类没实现这个接口,哪怕命名规范、放在 composer.json 的 autoload 里,也不会被识别为插件。
- 必须声明
use Composer\Plugin\PluginInterface;并implements PluginInterface -
activate()是唯一入口,$composer和$io在这里才首次可用 - 不能在
__construct()里访问$composer->getPackage()等方法——此时依赖图还没解析,会抛LogicException - 如果想支持旧版 Composer(Composer\Plugin\Capability\CommandProvider 等能力接口,否则命令不出现
EventDispatcher 是唯一合法的事件监听方式
Composer 内部用 Composer\EventDispatcher\EventDispatcher 分发事件,所有插件都必须通过它注册监听器——没有全局钩子、没有魔术方法、没有装饰器注册表。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 监听必须在
activate()中调用$dispatcher->addSubscriber($subscriber),传入实现了EventSubscriberInterface的对象 - 不要用
onPreAutoloadDump这类旧式字符串回调,已废弃且在 Composer 2+ 中直接忽略 - 事件名严格区分大小写:
PostInstallCommandEvent≠postinstallcommandevent - 常见事件如
PreInstallCommandEvent、PostUpdateCommandEvent触发时机不同:前者在锁文件生成前,后者在全部包下载解压后
监听器类必须实现 EventSubscriberInterface 并返回映射数组
这不是可选约定,而是硬性要求——Composer 通过 getSubscribedEvents() 的返回值决定哪些方法被调用,不返回或返回格式错误,监听器等于不存在。
-
getSubscribedEvents()必须是静态方法,返回形如['post-install-cmd' => 'onPostInstall']的关联数组 - 键是事件别名(如
post-install-cmd),不是类名;值是本类中方法名(字符串)或[method, priority]数组 - 优先级(priority)默认为 0,数值越大越早执行;若多个插件监听同一事件,优先级决定执行顺序
- 方法签名必须匹配事件类型:
onPostInstall(PostInstallCommandEvent $event),参数类型错误会导致运行时TypeError
事件对象里的数据不是全量可用,得看具体阶段
比如 PreInstallCommandEvent 里 $event->getComposer()->getPackage() 返回的是 root package 的初始定义,不含 require-dev 解析结果;而 PostUpdateCommandEvent 中才能拿到完整更新后的 LockFile 和实际安装的包列表。
-
CommandEvent子类(如PostUpdateCommandEvent)有getArguments()和getOptions(),但仅限用户显式传入的参数,不包含 Composer 自动推导的配置 - 修改依赖图要谨慎:在
PreInstallCommandEvent中调用$composer->getRepositoryManager()->setRepositoryClass(...)是安全的;但在PostInstallCommandEvent中再改就会被忽略 - 写入文件务必用
$io->writeError()而非echo,否则在静默模式(-q)下输出丢失,且破坏 Composer 的输出缓冲逻辑
最常被忽略的一点:Composer 插件的 autoloader 加载时机早于 root package 的 autoload 配置,所以插件里不能直接 new 项目代码中的类——除非你手动 require 或用 class_exists($class, false) 延迟加载。










