不能。--dry-run仅模拟依赖解析,不验证PHP版本、扩展缺失、运行时冲突或autoload问题;它成功仅表示约束可解,不代表实际可运行。

composer require --dry-run 能否真正预检兼容性?
不能。它只模拟安装流程,不验证实际运行时兼容性,更不会提前暴露平台缺失(如 PHP 版本、ext-zip)或冲突包的 runtime 行为问题。
执行 composer require guzzlehttp/guzzle:^8.0 --dry-run 时,Composer 仅做两件事:检查 composer.json 约束是否语法合法、尝试解析出一组满足所有依赖的版本组合。只要解析成功,就输出“would install”,但这个“会装”不等于“能跑”。
- 如果目标包要求 PHP 8.2+,而你本地是 8.1,
--dry-run不报错——它根本不去查 PHP 版本 - 如果某个已装包在
conflict字段里硬性禁止该版本(比如"conflict": {"guzzlehttp/guzzle": "^8.0"}),--dry-run会失败并提示冲突,这是它唯一有价值的信号 - 它无法发现 autoloading 冲突、函数名重定义、或 polyfill 覆盖不全导致的 fatal error
真正有用的预检命令组合
想提前知道能不能装、装了会不会崩,得用多个命令交叉验证,而不是依赖单一 --dry-run。
- 先查阻断链:
composer why-not guzzlehttp/guzzle:^8.0—— 输出谁在阻止、为什么阻止,比报错信息直白十倍 - 再看当前环境是否达标:
composer diagnose检查 lock 文件一致性、PHP 版本、扩展是否存在;配合php -v和php -m | grep zip手动确认关键扩展 - 最后验证目标包自身约束:
composer show guzzlehttp/guzzle ^8.0看它声明的require和conflict字段,尤其注意是否对symfony/*或psr/*有强绑定
为什么 --dry-run -v 仍常被误用?
加 -v(verbose)后输出变长,看起来很“专业”,但多数日志只是回显解析过程,比如 “Resolving dependencies through SAT” 或 “Found package guzzlehttp/guzzle at version 8.0.1”,这些不构成兼容性判断依据。
真正关键的线索藏在末尾几行:
- 出现
Conclusion: don't install ...→ 是约束冲突,可用why-not追根 - 出现
Package ... has a PHP requirement incompatible with your PHP version→ 是 platform 问题,这时才该考虑--ignore-platform-reqs(但仅限测试环境) - 全程无报错,只显示一堆
Installing ...→ 仅代表解析通过,不代表能加载、能调用、不出 Notice
CI/CD 中最该删掉的一行脚本
很多团队在 CI 脚本里写 composer require some/package --dry-run && composer install,以为加了预检就安全。实际上这行等价于“假装检查,然后直接上”。
真正健壮的流程是:
- 在 PR 阶段强制运行
composer why-not+composer validate+php -l检查新增配置文件 - CI 构建时用完整环境(匹配生产 PHP 版本和扩展)跑
composer install,失败即中断 - 绝不把
--dry-run当作质量门禁——它连门锁都没摸到
预检的本质不是“让 Composer 说可以”,而是“逼它说出为什么不可以”。盯着报错里的具体包名和约束条件,比反复重试 --dry-run 有效得多。


















