composer why-not是检测依赖死锁的起点,不是备选方案;它不模拟安装、不修改文件,仅从目标包反向遍历composer.json和composer.lock中的require、conflict及platform约束,精准输出首个不可绕过的硬冲突点,如conflicts行即为真死锁。

composer why-not 是检测依赖死锁的起点,不是备选方案
遇到 root requirements could not be resolved 报错时,别急着删 composer.lock 或改约束——composer why-not 是唯一能立刻告诉你“谁在拦路”的只读命令。它不模拟安装、不修改文件,只从目标包反向遍历当前 composer.json 和 composer.lock 中所有 require、conflict 和 platform 约束,输出第一个无法绕过的硬冲突点。
常见踩坑点:
-
composer why-not laravel/framework:11.0报[InvalidArgumentException] Package not found?缺了补零,必须写成laravel/framework:11.0.0 - 输出为空 ≠ 没问题,说明目标包未被任何现有依赖引用,要检查拼写、PHP 版本、
minimum-stability或私有仓库可达性 - 输出中出现
conflicts行(如conflicts: {"laravel/framework": ">=11"}),这就是真死锁,Composer 直接放弃求解 - 若目标包被
require-dev中的包间接依赖,必须加--with-all-dependencies才能穿透检查
用 composer prohibits 主动扫描阻断源头
当你准备升级主框架(如 Laravel 11)但还没写进 composer.json 时,composer why-not 会返回空——这时该用 composer prohibits。它不等你“想装什么”,而是主动扫描整个依赖图,列出所有明确声明排斥目标版本的包。
实操建议:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 升 Laravel 前先跑
composer prohibits "laravel/framework:11.0.0",提前看到spatie/laravel-backup或orchestra/testbench是否还在锁死旧版 - 输出中带
(by your requirements)的行,是你自己的composer.json在作祟,不是第三方包的问题 - 多个包都禁止同一版本时,优先处理
require-dev里的工具链包——它们常因测试兼容性滞后于主框架
依赖树分析:用 show -t --no-dev 定位循环引用
composer install 卡住不动、CPU 持续飙升、内存暴涨,大概率是循环依赖导致 SAT 求解器无限回溯。这不是网络慢,也不是包不存在,而是依赖图里存在 a → b → a 类型的强循环。
关键操作:
- 运行
composer show -t --no-dev --ignore-platform-reqs,才能逼近真实安装路径;默认行为会包含require-dev并跳过平台检查,掩盖真实冲突 - 人工扫描输出中反复出现的包名组合,比如:
vendor/a/package-a→vendor/b/package-b→ 又回到vendor/a/package-a - 某包在树中展开超过 3 次且路径不同,也值得怀疑;Windows cmd 可能截断长输出,建议用 PowerShell 或加
| more
封装可配置检测器:核心是命令组合与参数隔离
所谓“可配置的 PHP 分布式死锁检测器”,本质不是写新逻辑,而是把 why-not、prohibits、show -t 这三类命令封装成统一入口,并隔离参数干扰。例如一个 CLI 工具接受 --target、--mode=why-not|prohibits|tree、--include-dev 等开关,内部根据模式调用对应命令并过滤输出。
注意事项:
- 不要试图在 PHP 层解析 Composer 输出——直接
exec()调用原生命令更可靠,避免自己重实现约束解析 -
--dry-run -v在卡住时非常关键:它让日志吐出 SAT 求解器的真实决策痕迹,不是“日志”,是求解器的回溯路径 - 所有命令都依赖 Composer ≥ 2.2;低于该版本需先
composer self-update --2,否则提示Command "why-not" is not defined - 真正难处理的从来不是命令怎么写,而是如何判断“这个空输出到底是没冲突,还是环境不满足”——PHP 版本、扩展、私有源认证状态,
why-not都不校验
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










