composer install --dry-run 仅模拟依赖解析,不下载或写入文件,可提前暴露冲突但不校验权限、网络、PHP扩展等运行时条件,也不处理platform配置的动态覆盖。

composer install --dry-run 会跳过实际写入,只模拟依赖解析
它不会下载、解压或写入任何文件,也不会修改 vendor/ 或 composer.lock。核心作用是提前暴露依赖冲突、版本不可达、平台约束不满足等问题,比如 Your requirements could not be resolved 这类错误仍会报出,但不会导致项目状态被破坏。
- 适用于 CI 流水线中预检依赖变更是否合法
- 对
composer update同样有效,但要注意:它默认只模拟 root package 的更新范围,不递归展开所有包的更新候选(除非显式指定包名) - 不校验脚本钩子(如
post-install-cmd)是否能执行,这些在真实运行时才触发
--dry-run 不等于“安全模式”,它不检查权限、磁盘空间或网络可达性
它只做内存中的依赖图求解,不发起任何 HTTP 请求,也不检查本地目录是否可写。所以即使 --dry-run 成功,真实执行时仍可能因以下原因失败:
-
vendor/目录被设为只读,或父目录无写权限 - 目标包在 packagist.org 上已删除,但缓存中仍有元数据(
--dry-run不刷新远程索引) - PHP 扩展缺失(如 ext-zip),导致某些包安装后无法启用——这属于运行时检查,
--dry-run完全不涉及
与 composer why-not 和 composer prohibits 的配合使用场景
当 --dry-run 报出版本冲突时,单看错误信息往往不够定位。此时应立刻补查具体哪个依赖在阻断升级:
composer why-not monolog/monolog:^3.0 composer prohibits guzzlehttp/guzzle:7.8.0
这两个命令能快速定位冲突源头,比反复试错 --dry-run 更高效。注意:why-not 检查的是当前 composer.json 中声明的约束,而 prohibits 检查的是已安装包的约束(即 composer.lock 中已固化的依赖树)。
真实项目中容易忽略的关键点
--dry-run 不处理 platform 配置的动态覆盖。例如你在 composer.json 中写了:
"config": {
"platform": {
"php": "8.1.0"
}
}
但本地实际是 PHP 8.2,--dry-run 仍按 8.1 解析——它不读取运行时 PHP 版本,只认配置。这意味着你可能在开发机上看到成功,却在 PHP 8.1 的生产环境部署时失败。










