composer update --dry-run 不能真正避免报错,因它仅模拟依赖解析,不下载包、不解包、不执行脚本,也不验证PHP版本或扩展启用状态;它仅可靠检测依赖图冲突、平台硬约束冲突及已安装包降级不可行问题。

为什么 composer update --dry-run 不能真正避免报错
它只模拟依赖解析,不下载、不解包、不执行 post-update-cmd 等脚本,更不会验证 PHP 版本兼容性或扩展是否启用。常见误判包括:ext-redis 缺失、php >=8.2 要求被忽略、自定义 installer-paths 冲突未暴露。
--dry-run 能可靠检查哪些问题
它实际有效的是依赖图层面的冲突判断:
- 版本约束直接矛盾(如
"monolog/monolog": "^2.0"和"monolog/monolog": "^3.0"同时存在) - 平台配置不满足(
platform中声明的php、ext-*与包要求硬冲突) - 已安装包无法降级(比如
laravel/framework v10.30.0锁在composer.lock,但新规则强制要求v9.*)
比 --dry-run 更实用的预检组合
单靠它风险仍高,建议串联执行:
- 先运行
composer validate:确认composer.json结构和字段合法 - 再跑
composer prohibits vendor/package-name:查清某个包为何无法升级(比如谁在 requireguzzlehttp/guzzle:^7拦着^8) - 用
composer show --outdated分别看 major/minor 更新范围,避免盲升doctrine/dbal这类破坏性大版本 - 若项目有 CI,务必在相同 PHP+SAPI 环境下跑完整
composer update+ 测试,--dry-run不代替真实执行
真正容易被忽略的「安全」陷阱
很多人以为加了 --dry-run 就可放心合并 PR 或上线,其实最危险的是两类情况:
-
composer.lock被手动编辑过,--dry-run仍按旧 lock 文件解析,但实际更新会重写它,导致 diff 不可预测 - 私有仓库响应延迟或临时不可达,
--dry-run不校验网络可达性,等真跑时卡在Fetching packages或报Could not fetch https://...
预演不是兜底,它只是第一道过滤网。真实环境里的扩展加载、autoload 生成、脚本执行顺序,都得等真正跑起来才见分晓。










