--dry-run会完整执行依赖求解但跳过写入,必须加-v才能暴露降级、冲突、平台不兼容等关键风险;仅支持update、require、remove命令,install不支持。

composer update --dry-run 不是“看看而已”,它会真实跑完全部依赖求解逻辑,只跳过写文件;不加 -v 就等于没用——关键降级、冲突、隐性安全风险全被藏起来了。
为什么 composer update --dry-run 必须加 -v
默认输出只显示类似 Updating monolog/monolog (2.9.0 => 3.0.0) 这种单行摘要,但你看不到:
- 触发升级的到底是哪条
conflict规则 -
symfony/console为什么从 v6 降到了 v5.4(可能是某个新包强制要求 PHP 8.0,而你锁了"php": "8.1") - 私有源包元数据是否能正常解析(网络卡住时,
-v会暴露在哪个 repo 挂住) - 哪个包因平台扩展缺失(如
ext-igbinary)被排除,从而退而选择了更老的候选版本
composer update --dry-run 真实行为是什么
它不是打印个列表就结束。Composer 会:
- 重新读取
composer.json和composer.lock - 完整执行约束解析、版本回溯、冲突调解
- 算出每一项要
Updating/Downgrading/Installing/Removing的包和精确版本号 - 停在「准备写入」那一步:不改
vendor/、不重写composer.lock、不重建 autoloader
这意味着你能提前看到:Downgrading symfony/event-dispatcher (6.3.0 => 5.4.33) → 你的代码用了 StoppableEventInterface,运行时直接 Class not found。
哪些命令真正支持 --dry-run,哪些不支持
支持的只有这三个命令:
-
composer update --dry-run:重解析整个依赖图,看升降级全景 -
composer require vendor/package --dry-run(Composer 2.2+):预判新增是否引发冲突、是否强制升级已有包 -
composer remove vendor/package --dry-run:确认该包是否被其他依赖强引用,删了会不会连带卸载一堆东西
不支持的典型误用:
-
composer install --dry-run:报错Unrecognized option: --dry-run,官方从未实现 -
composer update --dry-run --no-interaction在 CI 中直接|| exit 1不够——它默认成功退出,即使检测到 PHP 版本不兼容也不会报错,必须人工扫输出或 grep 关键词
容易被忽略的三类问题,--dry-run 根本不检查
它再准也只是模拟 Composer 自身流程,以下必须手动盯:
- 网络与权限:
--dry-run会访问 Packagist 或私有源,但不验证 token 是否有效、代理是否放行、vendor/目录是否可写 - 扩展启用状态:
ext-gd或ext-redis是否已启用,得靠composer check-platform-reqs单独验证 - autoload 冲突:两个包都注册了
src/下相同命名空间前缀,require --dry-run完全不模拟,只有真跑composer dump-autoload才暴露
最易跳过的一步是:执行完 composer update --dry-run -v 后,不人工扫一眼 Downgrading 和 Installing new package 这两类行——它们背后大概率藏着 BC break 或未授权引入的第三方包。











