答案是创建一个实现PluginInterface的类并绑定事件。首先定义type为composer-plugin的包,通过extra.class指定入口类,在激活时监听如post-autoload-dump等事件以执行自定义逻辑。

编写一个 Composer 插件可以让你在 Composer 安装、更新或卸载包时执行自定义逻辑。这类插件通常用于自动注册服务、生成配置文件、清理缓存等任务。下面是如何从零开始创建一个简单的 Composer 插件。
理解 Composer 插件机制
Composer 使用插件系统允许第三方代码在核心命令执行前后注入行为。要成为合法插件,你的类必须实现 ComposerPluginPluginInterface,并在激活时绑定到事件钩子上。
Composer 提供多个事件,比如:
- init:项目首次初始化
- install-cmd:执行 install 命令后
- update-cmd:update 执行完成后
- post-autoload-dump:自动加载重建后(最常用)
创建插件项目结构
新建一个目录作为插件根目录,例如 my-composer-plugin,然后创建以下文件结构:
编辑 composer.json 内容如下:
“`json { “name”: “vendor/my-composer-plugin”, “type”: “composer-plugin”, “require”: { “composer-plugin-api”: “^2.0”, “composer/composer”: “^2.0” }, “autoload”: { “psr-4”: { “VendorMyPlugin”: “src/” } }, “extra”: { “class”: “VendorMyPluginMyPlugin” } } “`
注意:type 必须是 composer-plugin,且 extra.class 指定主类路径。
实现插件主类
在 src/MyPlugin.php 中编写插件逻辑:
“`php namespace VendorMyPlugin;
use ComposerComposer; use ComposerIOIOInterface; use ComposerPluginPluginInterface; use ComposerEventDispatcherEventSubscriberInterface; use ComposerScriptEvent; use ComposerScriptScriptEvents;
class MyPlugin implements PluginInterface, EventSubscriberInterface { public function activate(Composer $composer, IOInterface $io) { // 插件激活时绑定事件监听 }
public static function getSubscribedEvents() { return [ ScriptEvents::POST_AUTOLOAD_DUMP => 'onPostAutoloadDump', ]; } public function onPostAutoloadDump(Event $event) { $io = $event->getIO(); $io->write('<info>自定义插件:自动加载已重建,正在执行额外操作...</info>'); // 示例:生成一个日志文件 file_put_contents('plugin-ran.txt', 'Plugin executed at ' . date('Y-m-d H:i:s')); }
}
<p>这个插件在每次执行 <font>composer dump-autoload</font> 或安装/更新后自动运行,生成一个时间戳文件。</p> <H3>测试你的插件</H3> <p>在本地测试插件,推荐使用 path 方式引入:</p> <p>在一个测试项目中修改其 <font>composer.json</font>:</p> ```json { "repositories": [ { "type": "path", "url": "../my-composer-plugin" } ], "require": { "vendor/my-composer-plugin": "*" } }
运行 composer require vendor/my-composer-plugin,安装后执行 composer dump-autoload,你应该看到提示信息并发现生成了 plugin-ran.txt 文件。
基本上就这些。只要遵循接口规范,你可以扩展出更复杂的功能,比如扫描类注册服务、写入配置、触发外部构建脚本等。关键是理解事件生命周期和 Composer 对象的可用方法。