结论:必须用composer update --dry-run -v而非install --dry-run或update --lock,因前者完整执行依赖解析并暴露版本升降级、冲突降级等风险,后者仅校验lock一致性且无视composer.json变更。

直接说结论:用 composer update --dry-run,不是 install --dry-run,也不是 update --lock —— 后两者目的完全不同。
为什么 composer install --dry-run 不是你要的“模拟更新”
它只校验当前 composer.lock 是否能被安全还原,不看 composer.json 里改了什么。哪怕你刚把 "php": "^8.0" 改成 "^8.3",它也完全无视,只会告诉你 “Nothing to install”。它不重算依赖,不反映任何新约束带来的变化。
- 输出安静 ≠ 没事,可能只是 lock 文件还“凑合能用”
- 不访问 Packagist,不拉元数据,不检测版本兼容性漂移
- 无法发现因 PHP 版本放宽导致的意外升级(比如
symfony/console从 v5 跳到 v6)
composer update --dry-run 才是完整模拟的核心命令
它会真实走完依赖求解全流程:读 composer.json、合并 config.platform、解析所有约束、访问源获取最新版本元数据、处理 conflict 规则、计算出最终安装/升级/降级/移除列表 —— 唯一跳过的是写文件和执行脚本。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 必须加
-v(--verbose)才能看到关键细节:哪个包被降级、为什么回退到旧版、是否因 ext-zip 缺失而排除候选版本 - 指定包名可缩小范围:
composer update laravel/framework --dry-run -v,避免被无关包干扰 - 搭配
--with-dependencies才能暴露子依赖的连锁降级(例如你只动guzzlehttp/guzzle,但monolog被连带降级) - 注意退出码:冲突失败时返回 2,有变更计划或无变更都返回 0 —— 不能靠 exit code 判断“是否有风险”,得人工扫输出里的
Downgrading和Installing new package
别踩这些坑:常见误用与真实后果
composer update --dry-run 看似安全,但几个关键盲区容易漏掉:
-
--dry-run不校验运行时扩展是否真已加载(比如ext-gd在composer.json里声明了,但 php.ini 没开 —— 它不报错,等install才崩) - 私有仓库认证失败、镜像超时、token 过期等问题,往往在
--dry-run阶段不触发,要到真实install或update才暴露 - 它不会检查
autoload冲突(比如两个包都注册了"psr-4": {"App\": "src/"}),这类问题要等composer dump-autoload才浮现 - dev 依赖变更(如
phpunit升级)可能悄无声息影响测试行为,--dry-run完全不提示
真正麻烦的不是命令敲错,而是把 --dry-run 输出扫完就以为万事大吉 —— 它只解决“依赖图能不能算出来”,不保证“算出来的包跑得起来”。










