composer update --dry-run 是定位依赖冲突链最直接的方法,它不修改文件但完整执行依赖解析,逐层展开冲突路径,配合 -v、--no-dev 及 composer depends --tree、composer show、composer check-platform-reqs 可精准定位间接冲突与平台兼容问题。

composer update --dry-run 是定位冲突链最直接的命令
它不改任何文件,但会完整跑一遍依赖解析引擎,把冲突路径像剥洋葱一样一层层展开。错误信息里出现的 Conclusion: don't install xxx 或 Root requires yyy, but zzz requires incompatible version 就是真实矛盾点。
常见错误现象:执行 composer update 卡住不动、报错信息只显示“Your requirements could not be resolved”,却没指出谁在拉哪个版本——这时必须加 --dry-run 才能看到完整推导过程。
实操建议:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 优先用
composer update --dry-run -v(-v输出更详细) - 如果项目有大量
require-dev,可先试composer update --dry-run --no-dev缩小干扰范围 - 注意输出里反复出现的包名,比如多次看到
symfony/console被不同包以^5.4和^6.0拉入,它大概率就是冲突枢纽
composer depends --tree vendor/package 能查清谁在“偷偷”拉入某个包
很多冲突不是你直接写的 require 引起的,而是某个包的子依赖在暗处施压。比如你只写了 "laravel/framework": "^10.0",但它内部要求 monolog/monolog: "^3.0",而你另一个包又硬绑了 "monolog/monolog": "^2.8" —— 这时候光看 composer.json 根本发现不了。
实操建议:
- 对报错中高频出现的包,运行
composer depends --tree vendor/package-name,例如composer depends --tree monolog/monolog - 输出里会标出每个引用层级的约束条件,比如
your-project → laravel/framework[10.42.0] → monolog/monolog[^3.0] - 如果同一包被多个路径拉入且约束互斥,就确认是间接冲突源
composer show vendor/package x.y.z | grep require 用来验证具体版本实际依赖什么
^ 符号看着宽泛,但 Composer 实际选哪个版本,取决于当前 lock 文件或解析上下文。你写的是 "psr/log": "^1.0",但最终装进来的可能是 1.2.0 或 2.0.0,而这两个版本的 require 字段可能完全不同——前者要求 php: >=5.3.0,后者可能要求 php: >=7.4,这就埋下平台兼容隐患。
实操建议:
- 对关键中间包(如
psr/log、symfony/polyfill),运行composer show vendor/package x.y.z | grep require,例如composer show psr/log 2.0.0 | grep require - 重点比对
require里的php、ext-*和其他包约束,看是否和项目环境或其它依赖冲突 - 若发现某版本的
require明确列出ext-intl,但你的 PHP 没开这个扩展,那即使composer install成功,运行时也会崩
composer check-platform-reqs 比 diagnose 更贴近真实运行环境
composer diagnose 只检查 Composer 自身能否跑起来(比如有没有 json、mbstring),它不管你的项目代码到底要什么。而 composer check-platform-reqs(Composer 2.2+)会读取所有已安装包(含传递依赖)的 require 字段,汇总出整个依赖图真正需要的 PHP 版本、扩展、INI 配置等。
实操建议:
- 执行
composer check-platform-reqs --with-dependencies,确保递归检查全部依赖 - 如果报
ext-redis缺失,但php -m | grep redis看得见——大概率是 Composer 调用的 PHP CLI 和你手动执行的不是同一个二进制,用which php和composer config --global --list | grep bin-dir对齐路径 - 它不会检测
ini设置(如redis.session.locking_enabled)或功能残缺(如ext-gd编译时没带 PNG 支持),这些得靠人工核对或运行时日志反推
冲突排查最耗时间的环节,往往不是命令不会用,而是没意识到某个包的 require 字段里悄悄锁死了 PHP 小版本,或者某次 composer update 后 composer.lock 里混进了两个 major 版本的 psr/container,而 composer audit 根本不报这种事——它只管漏洞,不管兼容性。

















