直接运行 composer why-not 定位真实冲突源头,它输出反向依赖链,从最后一行根声明往上读,带 (required by) 的行即冲突起点;必须用完整版本号,如 guzzlehttp/guzzle:^8.0。

直接运行 composer why-not 查阻断链,别删 vendor 或 composer.lock——它们不是问题,只是结果。
用 composer why-not 定位真实冲突源头
报错里出现 don't install xxx 时,composer why-not vendor/package:version 是唯一能说清“谁在拦路”的命令。它输出的是反向依赖链,从最后一行(你的 composer.json 根声明)往上读,看到哪一行带 (required by) 提出互斥约束,就是冲突起点。
- 必须用完整版本号,比如
composer why-not guzzlehttp/guzzle:^8.0,写成^8或8可能返回空 - 如果输出为空,先检查
require-dev—— 很多冲突来自phpunit/phpunit或mockery/mockery拖着老版sebastian/exporter,间接锁死symfony/console - 加
--dry-run验证:比如composer require laravel/framework:11.0.0 --dry-run,能提前看到是否真能解出路径,不改任何文件
看真实依赖结构,别信 composer.json 里的“愿望清单”
composer show --tree 显示的是 vendor/ 和 composer.lock 的真实快照,不是你 composer.json 里写的理想状态。它能暴露你根本没意识到的间接路径。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 查某个包被谁引入:
composer show --tree | grep "symfony/console",看它是否标着(locked to 5.4.42) - 过滤关键段:
composer show --tree monolog/monolog | grep -A5 -B5 "guzzlehttp/guzzle",快速定位交叉依赖点 - 看到某包标着
(replaced)或(provided),得去它自己的composer.json里确认替代逻辑是否真正覆盖了运行时调用
定点更新,避免全量 composer update 触发 SAT 卡死
全量 composer update 容易让求解器陷入穷举,尤其在依赖多的项目里。升级单个包必须带 --with-dependencies,否则 Composer 默认拒绝更新其子依赖,哪怕新版本根本跑不起来。
- 正确写法:
composer update monolog/monolog --with-dependencies—— 只动它和直系依赖 - 错误写法:
composer update "monolog/monolog:^3"—— 引号 +^会让 Composer 自己找“最新兼容版”,不是你要的3.0.0 - 降级跨主版本(如从
guzzlehttp/guzzle:^8.0切回7.4.5),必须在composer.json里写死:"guzzlehttp/guzzle": "7.4.5",不能只写"^7.0" - 执行后立刻
git diff composer.lock,确认只有目标包及其直系依赖被改,没波及其他
镜像源和缓存问题常被误判为依赖冲突
卡在 Resolving dependencies 不一定是版本冲突,90% 是镜像没生效或缓存残留导致元数据旧、求解器瞎试。
- 验证镜像是否生效:
composer config -g repo.packagist输出应为完整 URL 字符串;composer show packagist/support的source.url应含mirrors.aliyun.com - 必须清缓存:
composer clear-cache;若怀疑 provider 同步滞后,加--refresh:composer update --refresh - 只要
composer.json里有"repositories"字段(哪怕空数组),全局镜像就会被丢弃——不是合并,是直接忽略 - 换镜像不能跳过 SAT 求解,但能让冲突暴露得更快更准;
--dry-run --verbose才能看到求解器到底卡在哪条路径上
复杂项目里,冲突往往藏在 require-dev 的 autoload 路径、私有包的 conflict 字段、或 composer.lock 里已失效的 dist URL 中——这些地方不报错,但会让 composer install 无声失败。










