composer插件必须同时满足type为"composer-plugin"、实现plugininterface并正确配置autoload,且在composer 2.2+中需显式声明allow-plugins,否则静默失效。

Composer 插件不会自动生效,哪怕代码写对了、类也实现了接口——它必须被声明为 type: "composer-plugin" 并作为依赖安装进项目,否则 composer install 根本不会加载你的类。
插件不被识别?先检查 type 和 PluginInterface 实现
Composer 只扫描已安装的包中同时满足两个条件的:一是 composer.json 里有 "type": "composer-plugin",二是主类实现了 ComposerPluginPluginInterface。漏掉任意一个,插件就静默失效,连 warning 都不给。
-
composer.json必须显式写"type": "composer-plugin",不能靠目录名或命名约定 - 主类必须实现
PluginInterface,且包含activate()和deactivate()两个方法(哪怕空实现) -
autoload映射必须与命名空间严格一致,例如"psr-4": {"MyVendor\MyPlugin\": "src/"}对应src/Plugin.php中的namespace MyVendorMyPlugin; - 依赖项里得有
"composer-plugin-api": "^2.0"(对应 Composer 2.x),版本不匹配会导致类找不到或方法不存在
activate() 不执行?验证 autoload 和事件注册时机
activate() 是插件真正“活起来”的入口,但它的调用前提是类能被自动加载、签名完全匹配。Composer 会静默跳过任何构造失败、autoload 失败或签名错误的插件。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 别在
__construct()里做重操作——$composer和$io是activate()的参数,不是构造时传入的 - 监听器必须在
activate()中注册:$composer->getEventDispatcher()->addListener('post-install-cmd', [$this, 'onPostInstall']) - 拼错事件名(如写成
postinstall-cmd)或大小写不对,都不会触发回调 - 回调函数签名要严格:接收一个
CommandEvent或其子类实例,不能少参数,也不能加默认值
读取项目配置和路径?永远别用 getcwd() 或硬编码
插件运行时的工作目录不可靠,getcwd() 和硬编码 ./composer.json 都会出错。所有路径和配置必须通过 $composer 实例获取。
- 想读当前项目的
composer.json内容?别直接file_get_contents('composer.json')——应该用$composer->getPackage()->getExtra() ?? [] - 项目根目录不是靠
getcwd()推,而是用$composer->getConfig()->get('vendor-dir')反推,或直接用$composer->getPackage()->getAutoload()读已解析的 autoload 映射 - 修改
composer.json是禁止操作;插件只能提示用户手动运行composer update,用$io->writeError()输出警告 -
post-autoload-dump触发时,autoloader 文件已经写入磁盘;若想注入 classmap,必须提前在pre-autoload-dump阶段修改$composer->getPackage()->getAutoload()
Composer 2.2+ 默认禁用插件?allow-plugins 是硬门槛
从 Composer 2.2 开始,所有 type: "composer-plugin" 的包默认被禁用,composer install 会直接中断并提示 "Plugin installation is disabled"。这不是配置遗漏,而是强制安全策略。
-
allow-plugins必须写在项目composer.json根级,不能放在config或extra下 - 值必须是字符串数组,包名大小写敏感、无通配符,例如:
"dealerdirect/phpcodesniffer-composer-installer" - 如果用了
composer global require安装插件,全局配置也需设config.allow-plugins(路径通常为~/.composer/config.json) - 运行
composer show vendor/package-name,检查输出中是否有types : composer-plugin—— 没有就说明 Composer 根本没把它当插件看
最易被忽略的是 allow-plugins 的显式声明和 pre-autoload-dump 中修改 autoload 配置的时机——这两个点一旦出错,插件逻辑可能完全无法介入关键流程,且没有任何报错提示。










