Composer依赖冲突需先用composer why-not定位阻塞包,再检查minimum-stability、platform配置及PHP/扩展环境一致性,优先分批升级、收窄版本范围,避免ignore-platform-reqs和replace等危险操作。

composer install 报错 “Conclusion: don’t install xxx” 怎么办
这是最典型的依赖冲突提示,composer install 或 composer update 时出现一堆 “Conclusion: don’t install…” 或 “it requires xxx but you have yyy” 的回溯链,本质是 Composer 找不到一组能同时满足所有包版本约束的解。
- 先运行
composer why-not vendor/package:version(比如composer why-not laravel/framework:v10.0.0),它会告诉你哪个已安装包在阻止该版本被安装 - 检查
composer.json中的"minimum-stability"和"prefer-stable"设置:如果设了"minimum-stability": "dev",可能意外拉入不兼容的开发版;建议显式设为"stable"并开启"prefer-stable": true - 不要盲目加
--ignore-platform-reqs,它绕过 PHP/扩展版本检查,可能让项目跑起来但实际运行时报错
require 两个包却提示它们互斥,怎么协调
比如 A 包要求 "monolog/monolog": "^2.0",B 包要求 "monolog/monolog": "^3.0",Composer 就无法共存。
- 查看两者的最新稳定版是否已支持同一主版本:用
composer show monolog/monolog看当前锁定版本,再查 A/B 包的 GitHub README 或 packagist 页面,确认它们各自对monolog的require字段是否已更新 - 如果 A 包尚未适配 Monolog 3,而你又必须用 B 包,可临时 fork A 包、修改其
composer.json中的 monolog 约束(如改为"^2.0 || ^3.0"),然后在自己项目的repositories中指向这个 fork - 避免用
replace或provide强行“冒充”兼容——这会让依赖解析失效,后续 update 更难处理
composer update 卡住或耗时极长
这不是报错,但属于冲突的隐性表现:Solver 正在穷举组合,说明约束太紧或版本范围太宽(比如用了 "*" 或 "dev-main")。
- 运行
composer update --dry-run -v,加上-v可看到 solver 每一步尝试,快速定位哪几个包在反复回溯 - 把模糊版本号收窄:把
"^1.0"换成"^1.5",或把"dev-develop"换成具体 commit hash("dev-develop#abc123") - 若项目长期未 update,别直接
composer update,改用composer update vendor/package --with-dependencies分批升级,减少 solver 空间维度
本地能装,CI 上失败,平台差异怎么排查
常见于本地 PHP 8.2、CI 用 PHP 8.1,或本地有 ext-intl、CI 没装。
- 在 CI 脚本开头加
php -v && php -m | grep -E 'intl|mbstring',确认运行时环境一致 - 检查
composer.json的"platform"配置:如果写了"php": "8.2.0",但 CI 是 8.1,Composer 会拒绝安装需要 8.2+ 的包;应删掉"platform"或按 CI 环境设为最低支持版本 -
composer.lock必须提交进 Git,且确保生成它的 Composer 版本不低于 CI 使用的版本(例如 lock 文件由 Composer 2.5 生成,CI 不能用 2.2)
真正麻烦的不是报错本身,而是冲突根源藏在间接依赖里——composer show --tree 输出可能有 5 层深,其中第三层某个 dev 分支包悄悄锁死了某个组件的旧版。这时候得一层层 composer why 往上摸,而不是盯着最外层的 require 行改。










