不能直接修改 Composer 内置 Solver 类或 vendor 源码,因其是深度耦合 CDCL 算法的约束求解器;唯一安全方式是在 pre-pool-create 事件中通过插件干预请求与仓库。

不能直接修改 Composer 内置的依赖解析逻辑;唯一安全、可维护的方式是通过插件机制,在 pre-pool-create 事件中干预输入约束或仓库,而非重写求解器本身。
为什么不能 patch Solver 类或改 vendor/composer/src/?
Composer 的 Solver 是自研回溯式约束引擎,深度耦合版本区间处理、单元传播、冲突学习(CDCL)和缓存机制。手动修改源码会导致:
- 每次
composer self-update后立即失效 - 破坏
composer.lock的验证逻辑,引发校验失败或静默降级 - 跳过版本互斥检查、PHP 环境约束推导等关键步骤,产生运行时冲突
- 无法与
--with-dependencies、--dry-run等功能协同工作
pre-pool-create 是唯一可靠的干预时机
依赖解析真正开始前,Composer 会触发 pre-pool-create 事件,此时 $event->getRequest() 包含所有待解析的包约束,$event->getPoolBuilder() 允许你注入自定义仓库或装饰原始仓库链。这是唯一既不绕过求解器、又能影响最终结果的位置。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 可安全重写
require中的模糊约束,如把"monolog/monolog": "dev-main"替换为"monolog/monolog": "2.9.0" - 可添加
ArrayRepository提供虚拟包,用于桥接私有组件或强制提供某接口实现 - 必须用
RepositoryManager::addRepository()注入,而非替换整个仓库管理器,否则丢失 packagist.org 等默认源 - 避免在该事件中执行远程请求或耗时操作,否则会拖慢整个解析流程
composer prohibits 和 -vvv 日志才是调试真实依据
你以为改了约束就能绕过冲突?实际生效与否,得看求解器是否接受。别猜,用工具验证:
- 运行
composer prohibits vendor/package:1.2.3查看哪个依赖项在阻止该版本——它反映的是 SAT 求解器已确认的冲突链,不是配置文件表面写法 - 加
-vvv运行composer update,重点观察Resolving dependencies阶段中 “excluded by” 后面的排除原因,那是单元传播的实际推导结果 - 设置
COMPOSER_VERBOSE_SOLVER=1会打印每一步变量赋值与冲突子句,但日志量极大,建议配合grep -A5 -B5 "conflict"过滤 - 注意:如果
composer.lock存在且未被删除,update默认走“最小变更”路径,可能掩盖你插件中新规则的真实效果;测试时应先rm composer.lock
真正难的不是写插件,而是理解求解器看到的世界——它不认语义版本号,只认布尔变量和逻辑子句;你塞进去的每个约束,都会被翻译成 CNF 中的一条子句,然后参与全局推理。漏掉一个 conflict 声明,或错估一个 replace 的排斥范围,就可能导致无解证明提前触发。

















