Composer插件必须声明type:"composer-plugin"并作为项目依赖安装,且主类实现PluginInterface接口;监听事件需在activate()中注册,post-autoload-dump是代码生成的唯一可靠时机。

Composer 插件不会自动生效,哪怕代码写对了、类也实现了接口——它必须被声明为 type: "composer-plugin" 并作为依赖安装进项目,否则 composer install 根本不会加载你的类。
插件能被识别的两个硬性条件
Composer 只扫描已安装的包中同时满足以下两点的:一是 composer.json 里有 "type": "composer-plugin",二是主类实现了 Composer\Plugin\PluginInterface。漏掉任意一个,插件就等于不存在。
- 常见错误是只写了类、没改
type,或者写了type却忘了在autoload中正确映射命名空间(比如"psr-4": {"MyPlugin\": "src/"}对应文件路径src/Plugin.php) -
PluginInterface要求实现activate()和deactivate()方法,哪怕空着也得有;不实现会直接跳过加载 - 别指望靠
composer global require让插件对当前项目生效——全局插件只影响全局命令,项目级插件必须出现在项目composer.json的require或require-dev里
事件监听必须在 activate() 里注册
插件不是靠“执行”工作的,而是靠监听 Composer 生命周期事件。所有监听器都得在 activate() 方法里通过 $composer->getEventDispatcher()->addListener() 注册,不能写在构造函数或类属性里。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 事件名是纯字符串,大小写敏感:
"post-autoload-dump"有效,"post_autoload_dump"或ScriptEvents::POST_AUTOLOAD_DUMP都无效 - 回调函数签名必须严格匹配,例如监听
post-autoload-dump时,参数类型得是Composer\EventDispatcher\Event或其子类,不能是ScriptEvent -
activate()只在插件首次加载时调用一次,不适合放业务逻辑;真正干活的代码得塞进监听器函数里 - 别在
activate()里调用dump-autoload或触发重安装——这会引发递归,报Maximum function nesting level
读取项目配置和路径的唯一安全方式
插件运行时的工作目录不可靠,getcwd() 和硬编码 ./composer.json 都会出错。所有路径和配置必须通过 $composer 实例获取。
- 项目根目录不是靠
getcwd()推,而是用$composer->getConfig()->get('vendor-dir')反推,或直接用$composer->getPackage()->getAutoload()读已解析的 autoload 映射 - 想读用户自定义配置?走
$composer->getPackage()->getExtra(),比如"extra": {"myplugin": {"enabled": true}},然后手动做键存在性和类型校验 - 修改
composer.json是禁止操作,插件只能提示用户手动运行composer update,用$io->writeError()输出警告 - 生成文件时若需区分环境,检查
$event->isDevMode(),避免在生产环境误写入调试代码
为什么 post-autoload-dump 是代码生成类插件的唯一可靠时机
很多插件想生成代理类、路由表或配置文件,但选错事件就会读到残缺的 autoload 数据。只有 post-autoload-dump 触发时,vendor/autoload.php 已写入磁盘,所有包的 PSR-4/PSR-0 映射已完成合并。
-
post-install-cmd触发太早:vendor 目录刚解压完,autoload 文件还没生成,getAutoload()返回的可能是空或旧缓存 -
post-autoload-dump是唯一能保证$composer->getPackage()->getAutoload()返回完整、准确映射的事件 - 路径值如
["src/"]是相对于项目根目录的,不是绝对路径;拼绝对路径要用$composer->getConfig()->get('vendor-dir')或__DIR__配合项目根推导 - 生成前务必检查目标文件是否已存在、内容是否变更,避免无意义覆盖或与用户手写类冲突
最易被忽略的是:所有事件监听器共享同一个 $composer 实例内存状态,没有隔离上下文。你不能假设每次命令都是干净的——上一次 install 留下的临时变量可能还在那里。

















