别删 vendor 或 composer.lock,先运行 composer why-not 定位阻塞链——90% 冲突可在 3 分钟内找到根因;报错中“don’t install x:vy.z”是 sat 求解结果而非原因,真实拦路虎常是中间依赖锁死版本。

直接结论:别删 vendor 或 composer.lock,先跑 composer why-not 定位阻塞链——90% 的冲突靠它 3 分钟内定位到根因。
报错里 “don’t install X:vY.Z” 不是原因,只是数学结论
Composer 报的 Conclusion: don’t install laravel/framework:11.0.0 这类信息,是 SAT 求解器算完后给出的“无解”结果,不是 bug,也不是包本身有问题。真正卡住你的,是某个中间依赖悄悄锁死了版本。
- 运行
composer why-not laravel/framework:11.0.0(注意写全包名+精确版本,别用^11.0) - 输出是一条反向链:最后一行是你
composer.json的根声明,往上每行末尾的(required by ...)是向上追溯起点 - 重点看中间某行,比如
spatie/laravel-backup v7.2.0 requires symfony/console ^5.4—— 这才是真实拦路虎 - 如果输出为空,说明目标版本根本没发布,或你输错了格式(比如漏了
laravel/framework:前缀)
别信 composer.json 里写的“愿望”,要看 composer show --tree 真实快照
composer show --tree 显示的是 vendor/ 和 composer.lock 的实际状态,不是你想象中的依赖关系。很多冲突藏在第二、三层间接引入路径里。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 查某个包被谁引入:
composer show --tree | grep "guzzlehttp/guzzle" - 发现同一包被多个路径引入不同版本?比如
symfony/console同时出现在laravel/framework和phpunit/phpunit下 → 典型间接冲突 - 看到
(replaced)或(provided)标记?立刻去对应包的composer.json查replace字段,确认是否真能等价 - Composer 2.5+ 已移除
--tree参数,改用composer show --format=tree
composer update 必须加 --with-dependencies,否则等于没更新
想升一个包却只写 composer update monolog/monolog,Composer 默认拒绝更新它的子依赖。结果就是父包版本升了,子依赖还卡在旧版,新代码直接报错。
- 定点升级:用
composer update monolog/monolog --with-dependencies - 降级跨主版本(如从
guzzlehttp/guzzle:^8.0切回7.4.5),必须在composer.json里写死"guzzlehttp/guzzle": "7.4.5",不能只写"^7.0" - 执行后立刻
git diff composer.lock,确认只有目标包及其直系依赖被改动 —— 如果改动范围过大,说明你该换策略了 - 别写
composer update "monolog/monolog:^3":引号 +^会让 Composer 自己找“最新兼容版”,不是你要的3.0.0
环境不匹配常被误判为依赖冲突
很多 “无法解析依赖” 实际是 PHP 版本、扩展或平台约束不满足,和包本身无关。
- 检查报错里是否含
requires php >=8.1,而你本地是 PHP 7.4 → 升级 PHP 或换包 - 运行
composer diagnose,它会提示缺失的扩展(如intl、mbstring) - 某些包要求特定扩展但没明说,比如
ext-xml缺失会导致symfony/console安装失败 -
composer install失败但composer update成功?很可能是composer.lock记录了已失效的 dist URL(如 GitHub release 被删),此时可试composer clear-cache再重试
最危险的操作是删 composer.lock 后重装 —— 它不会“修复”冲突,只是把旧问题换成新问题。真正的难点从来不在命令怎么敲,而在读懂 why-not 输出里那条链上,哪一行才是真正动不得的“锚点”。










