composer卡在“resolving dependencies”是sat求解器穷举版本组合后确认无解,真实报错为“dependency resolution failed”,主因是约束不可满足而非死循环;require-dev全程参与求解,易因宽松约束、版本不交叠或minimum-stability设为dev加剧冲突;定位需用composer update -vvv结合grep分析日志,或composer depends --tree追溯源头。

为什么 composer update 会卡在 “Resolving dependencies” 几十秒才报错
这不是死循环,是 SAT 求解器穷尽所有版本组合后确认无解。真实错误是 Dependency resolution failed: unable to resolve packages for the given constraints,常伴随类似 The package "a" requires "b:^2.0", but "b" requires "a:^3.0" 的说明。
-
require-dev全程参与求解——哪怕你只在某个子包的require-dev里写了"phpunit/phpunit": "^9.0 || ^10.0",它也会和根项目、所有已安装包的 PHP 版本约束一起被反复比对 - 本地
composer.json中设了"minimum-stability": "dev",会让求解器尝试大量dev-main、dev-develop分支,解空间爆炸式增长 - 两个不同层级的包都通过
require-dev引入同一工具(如phpstan/phpstan),但版本范围不交叠(比如一个要^1.10,另一个锁死^2.0),Composer 就必须来回回溯、放弃、重试
怎么快速定位哪个包在“拖后腿”
别信报错最后一行——它只显示失败快照。真正有用的是详细日志里的选择与拒绝链。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 用
composer update -vvv 2>&1 | grep -E "(conflict|requires|chose|Rejecting)"抓关键行。例如某行显示chose vendor/x 1.2.0,紧接着几行又出现Rejecting vendor/x 1.2.0 because it requires vendor/y ^3.0,那vendor/x就是冲突源头之一 - 用
composer depends --tree vendor/problematic-package查它被谁层层 require。注意:如果返回not found in your dependencies,说明它没被你直接声明,而是某个已安装包的子依赖带进来的 - 对上层包执行
composer show -t upper/package,逐级往上翻,重点检查那些composer.json里写了"^99.0"、"dev-main"或宽松php约束的包
path 仓库在多模块项目中怎么避免踩坑
用 repositories + type: "path" 是 Monorepo 和多模块项目的常用手法,但路径解析和符号链接容易出问题。
- 本地包的
name字段必须和你在主项目require中写的完全一致,包括大小写和斜杠方向,否则 Composer 会静默跳过该 path 仓库 - 默认行为是创建 symlink,但某些 CI 环境或 Windows 非管理员权限下会 fallback 成 copy。可通过
"options": {"symlink": false}显式控制,避免本地调试时改了代码却没生效 - 生产部署前务必移除
repositories块并切换到私有源(如 Satis 或 Private Packagist),否则composer install会因找不到本地路径而失败 - 如果多个 path 包互相依赖,确保它们的
autoload配置不冲突,尤其是 PSR-4 的命名空间前缀不能重叠,否则自动加载器会随机加载错文件
composer.lock 不是万能依赖快照,哪些情况它会失效
vendor/composer/installed.json 和 composer.lock 都不能当绝对权威,尤其在多层级、多仓库场景下。
-
composer.lock只记录composer install或update当时的解析结果。如果你手动删了vendor/里的某个包但没运行update,lock文件里还留着它;反之,改了composer.json却没update,lock就已滞后 -
installed.json是运行时快照,但它不反映声明意图。比如你用path仓库装了一个本地包,installed.json里会记它的实际路径,但不会体现这个路径来自repositories还是 Packagist - 当使用
composer-bin-plugin或其他插件隔离 CLI 工具时,它们的依赖不写入主lock,也不出现在show -t默认输出里——得单独进vendor-bin/xxx/composer.json查
require-dev 里一个没声明在根项目中的工具,而那个工具又间接拉进了 C 包的 dev-only 依赖。查的时候得从报错包往回翻三层,再横向扫一遍所有 require-dev。










