composer插件必须实现plugininterface并正确配置autoload,通过commandevent监听命令,在activate()中注册;用getlocalrepository()获取已安装包版本,发布时需设type为composer-plugin且声明extra.plugin-class。

Composer插件必须实现 PluginInterface 才能被识别
Composer 不会自动加载任意 PHP 类作为插件,它只认实现了 ComposerPluginPluginInterface 的类,并且该类需在 composer.json 的 "autoload" 中正确声明。漏掉接口实现或 autoload 配置错误,会导致插件完全不加载——连报错都不会有,静默失效。
实操建议:
- 插件主类必须
implements ComposerPluginPluginInterface,不能只写个普通类然后指望 Composer 调用 -
composer.json中的"autoload"至少要包含"psr-4"映射,比如"MyVendor\VersionCheck\": "src/" - 运行
composer global require your/plugin后,执行composer show --plugins确认是否列出来了;没出现就说明加载失败
监听 CommandEvent 是检查版本的核心入口
想在用户执行 composer install 或 composer update 时触发检查,不能靠构造函数或静态方法,必须监听命令事件。Composer 插件通过 activate() 方法注册事件监听器,最常用的是 CommandEvent,它在命令开始前触发。
实操建议:
- 在
activate()中调用$event->getIO()->writeError()输出警告(注意是writeError,不是write,否则可能被静音) - 不要在监听器里 throw Exception,这会中断整个 Composer 流程;用
writeError+exit(1)更可控(但慎用 exit,可能影响 CI) - 获取当前项目根目录用
$event->getComposer()->getConfig()->get('vendor-dir')的父级路径,别硬写./
PackageInterface 和 RepositoryManager 是读取依赖版本的关键
插件没法直接读 composer.lock 文件内容来判断版本,得走 Composer 内部对象模型。真正可靠的方式是:从 $event->getComposer()->getRepositoryManager()->getLocalRepository() 拿到已安装包集合,再遍历每个 PackageInterface 实例的 getVersion() 和 getName()。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
实操建议:
-
getVersion()返回的是规范化的稳定版本号(如2.3.4),不是dev-main这类开发分支别名;如需比对分支,得查getExtra()['branch-alias']或getDistReference() - 注意区分
getRequires()(声明的依赖)和getLocalRepository()(实际安装的),版本检查一般用后者,更真实 - 避免在循环中反复调用
getPackage()或解析 JSON,性能差;一次性取全再过滤
发布为全局插件时,type: composer-plugin 和 extra.plugin-class 缺一不可
很多人把插件打包成 type: library,结果 composer global require 成功但插件不生效。Composer 全局插件必须显式声明 "type": "composer-plugin",并指定入口类路径,否则不会尝试实例化。
实操建议:
-
composer.json必须含"type": "composer-plugin" - 必须加
"extra": { "class": "MyVendor\VersionCheck\VersionCheckPlugin" },路径要和 autoload 完全一致 - 测试前先删掉
~/.composer/vendor/your/plugin和~/.composer/composer.lock,再重装,避免缓存干扰 - CI 中若用
--no-plugins,插件会被跳过,这不是 bug,是预期行为
插件逻辑看似简单,但 Composer 的生命周期钩子、对象模型抽象、以及全局 vs 本地作用域差异,会让很多判断失效。尤其要注意 getLocalRepository() 在 install 前是空的,而 update 时才可用——这个时机差,最容易写出“有时管用有时不报错”的半成品。










