要在 composer 插件中实现包安装前的前置校验逻辑,核心是监听 pre-package-install 事件,在 activate() 中注册回调,通过 packageevent 获取待安装包并执行轻量幂等校验,失败时抛出 runtimeexception 中断流程;插件需声明 type=composer-plugin 并正确配置 autoload 和 extra.class。

要在 Composer 插件中实现包安装前的前置校验逻辑,核心是监听 pre-package-install 事件,并在回调中对即将安装的 Package 对象执行检查。这不是靠修改 installer 或 downloader 完成的,而是通过插件事件系统在安装动作真正发生前介入。
监听 pre-package-install 事件
该事件在每个包开始安装前触发,参数为 PackageEvent,可获取待安装包、当前环境、IO 输出等关键信息。必须使用事件名字符串 "pre-package-install"(不是 ScriptEvents 常量),且回调函数签名需接收 PackageEvent 实例。
- 在插件主类的
activate()方法中注册监听器 - 回调内调用
$event->getOperation()->getPackage()获取目标 Package - 可通过
$package->getName()、$package->getVersion()、$package->getExtra()等读取元数据 - 若校验失败,抛出
RuntimeException即可中断安装流程(Composer 会捕获并显示错误)
常见校验场景与写法示例
校验逻辑应轻量、确定、幂等。典型用例包括:检查 PHP 版本兼容性、验证包签名字段、确认 extra 配置是否存在必需键、拦截黑名单包名。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 检查
extra.required-env是否满足(如要求"prod"环境才允许安装) - 读取
$package->getDist()['type'] ?? null判断是否为私有 dist 类型,再校验 token 有效性 - 解析
$package->getRequire(),禁止引入已知存在 CVE 的依赖版本范围 - 结合
$io->isInteractive()决定是否跳过校验(开发调试时可绕过)
注意 Package 对象不可变与时机限制
Package 实例在事件中是只读的,任何修改(如 setVersion)无效;校验必须在 pre-package-install 中完成,post-package-install 已无法阻止安装行为。同时,不要在此处尝试访问本地仓库或写文件——它发生在下载和解压之前,路径尚未生成。
- 不推荐在该事件中发起网络请求(如校验远程签名服务),会显著拖慢安装速度且易失败
- 避免依赖
$composer->getPackage()(这是 root 包,不是当前操作的包) - 若需跨包关联校验(如 A 包安装时检查 B 包是否已存在),要用
$composer->getRepositoryManager()->getLocalRepository()->findPackage()
配合 composer.json 声明确保插件被加载
插件包自身必须在 composer.json 中正确声明类型与自动加载:
-
"type": "composer-plugin"是强制要求,否则 Composer 不识别为插件 -
"autoload": {"psr-4": {"MyVendor\MyPlugin\": "src/"}}确保类可被发现 -
"extra": {"class": "MyVendor\MyPlugin\ValidatorPlugin"}指定入口类(Composer 2.2+ 推荐方式) - 项目 require 该插件后,无需额外启用,Composer 启动时自动激活










