pre-pool-create是唯一能真正干预依赖解析的事件,因其在pool构建前触发,可安全修改$request中的约束或仓库;其他事件如pre-package-install已无法改变solver计算出的版本组合。

pre-pool-create 是唯一能真正干预依赖解析的事件
想在 Composer 安装前修改依赖约束、屏蔽特定包、或注入私有仓库?必须用 pre-pool-create。其他事件如 pre-package-install 或 post-install-cmd 都太晚了——此时 Solver 已算出版本组合,你看到的已是“既定事实”,改不了求解结果。
关键点在于:Composer 的依赖解析分三步——收集 require → 构建 Pool(所有候选包版本集合)→ Solver 计算满足约束的组合。pre-pool-create 是 Pool 构建前的最后一个钩子,$event->getRequest() 暴露的是原始 Requirement 列表,可安全替换约束对象。
- 直接修改
$requirement->setConstraint(),别拼接字符串;用new Constraint('==', '1.2.3')保证语义合规 - 想过滤某包的所有 dev 版本?往
$event->getRepositories()插入一个FilterRepository,而不是删原仓库 - 改完必须调
$event->setRequest($modifiedRequest),否则变更完全不生效——这是插件开发里最常漏的一步 - 别在循环里反复调
$composer->getRepositoryManager()->repositories,它返回的是缓存副本,不影响当前事件上下文
监听 PackageEvents::PRE_PACKAGE_INSTALL 只能做单包级事后拦截
如果你的目标不是改解析逻辑,而是“发现高风险包就中断安装”,PackageEvents::PRE_PACKAGE_INSTALL 更合适。它在每个包解压前触发,参数是即将安装的 PackageInterface 实例,可检查包名、维护者邮箱、是否签名、composer.json 里是否含可疑关键词(如 eval、shell_exec)。
注意:PRE_PACKAGE_INSTALL 在 Composer v2.5+ 才稳定支持;v2.4 及以下得退回到监听 CommandEvent,再手动解析 $input->getArgument('packages') 或读取 composer.lock 预判。
- 匹配黑名单时建议用完整包名(如
monolog/monolog),避免误杀monolog-extra - 检查维护者邮箱可用正则
/@malicious\.example\.com$/i,但需注意公共镜像可能不暴露 maintainer 字段 - 中断必须抛
RuntimeException,不能只echo或return,否则流程继续 - 该事件无法阻止包被 Solver 选中,只能在下载后、解压前卡住——所以它防不了“合法包含恶意代码”,只防已知风险元数据
allow-plugins 和 --no-plugins 不是可选项,是执行闸门
插件本身能否加载,取决于 allow-plugins 白名单和命令行参数。Composer 2.2+ 默认 "allow-plugins": {"*": false},意味着任何插件(包括 symfony/flex)都进不来,除非你在 composer.json 里显式授权。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
CI/CD 中必须同时控制两层:配置白名单 + 命令行禁用。漏掉任一环,都可能让恶意插件绕过检查。
-
"config": {"allow-plugins": {"my-security-plugin": true}}—— 包名必须完全匹配,不支持通配符 - 部署时加
--no-plugins,且位置必须是composer install --no-plugins,写成composer --no-plugins install无效 - 如果插件报错说“dependency plugin not allowed”,说明它依赖另一个未授权插件,得顺藤摸瓜补全白名单
-
allow-plugins: true等价于关掉全部插件安全机制,生产环境绝对禁止
CI 流水线里插件不触发?先查 composer-plugin-api 版本对不对
现象是 activate() 执行了,但 onPrePoolCreate 根本没进断点。90% 是因为 composer-plugin-api 版本与当前 Composer 主版本不匹配。
运行 composer --version 查主版本(如 2.7.3),然后在插件的 composer.json 中严格匹配:"composer-plugin-api": "^2.0"。写成 "^1.0" 或 "^2" 都会导致事件注册失败。
- 事件注册必须在
activate()方法内完成,且签名要一字不差:$eventDispatcher->addListener('pre-pool-create', [$this, 'onPrePoolCreate']) - 事件名是字符串
'pre-pool-create',不是常量PluginEvents::PRE_POOL_CREATE(后者是旧版写法,v2.5+ 已弃用) - 插件类必须实现
Composer\Plugin\PluginInterface,且activate()第二个参数是Composer\Composer实例,不是IOInterface
复杂点在于:同一个插件,在本地 composer install 和 CI 的 composer install --no-interaction 下行为可能不同——前者会触发交互式提示(比如问你是否信任某个插件),后者直接按白名单走。别假设本地跑通,CI 就一定生效。










