composer update --dry-run -v 可预演升级影响:不改文件但完整执行SAT求解,末尾列出所有将安装/降级/移除的包;重点关注核心框架变动、dev包误删及“Trying/Reverting”循环。

composer update --dry-run -v 能看出实际影响范围
直接跑 composer update 可能悄悄升级几十个包,而你只关心其中一两个。用 --dry-run -v 是最轻量的预演方式——它不改任何文件,但会完整走一遍 SAT 求解流程,并在日志末尾列出所有将被安装/降级/移除的包及其版本。
重点关注三类输出:
- 「Installing」和「Downgrading」行:确认是否动了核心框架(如
laravel/framework、symfony/http-kernel) - 「Removing」行:警惕被连带删掉的 dev-only 包(比如
phpunit/phpunit或mockery/mockery),它们可能被 require-dev 里的其他包间接依赖 - 反复出现的 「Trying」+「Reverting」循环:说明求解器在暴力试探,此时真实执行大概率卡住或超时
composer show --tree | grep 关键包名 可定位隐性依赖
你以为只改了 monolog/monolog,但 composer show --tree 可能暴露出它被 spatie/laravel-ignition(require-dev)和 laravel/sanctum(require)同时拉入,且两者对 PHP 版本要求不同。这种跨环境的隐性依赖,是冲突复现难、上线后报错的核心原因。
实操建议:
- 先过滤出生产环境依赖:
composer show --tree | grep -E "^[a-z]" | head -20(避免被 require-dev 的长树淹没) - 检查关键包是否出现在多个层级:比如
guzzlehttp/guzzle同时出现在laravel/framework和aws/aws-sdk-php的子树里,说明它被两套逻辑共同约束 - 注意版本号后缀:带
-dev或-beta的包,可能触发minimum-stability全局降级,进而松动其他包的约束
composer why-not 比报错信息更准,但要指定具体版本
报错里写的 Your requirements could not be resolved 是结果,不是原因。真正卡住你的,往往是某个包把依赖死锁在旧版。比如 composer why-not monolog/monolog:2.9.0 返回:
monolog/monolog 2.9.0 requires php ^7.2 || ^8.0 ├── package-x v1.5.0 requires monolog/monolog ^1.25 └── package-y v2.1.0 requires php >=8.1
这说明问题不在 monolog 本身,而在 package-x 的硬约束。此时你要做的是:
- 查
package-x是否有新版支持monolog:^2.0(去 Packagist 看它的 latest tag) - 如果没更新,就别强推
monolog:2.9.0,改用兼容交集版本,比如"monolog/monolog": "^1.25 || ^2.4"(前提是你的代码真能处理两套 API) - 临时加
--with=package-x:dev-main测试是否只是版本滞后,而非设计冲突
锁文件冲突时别手动编辑 composer.lock
Git 合并导致 composer.lock 出现 composer install。这是危险操作——composer.lock 不是配置文件,它是依赖图的哈希快照,手动拼接会破坏 content-hash 校验,导致 composer install 失败或 vendor 目录不一致。
正确做法只有两种:
- 接受一方的 lock 文件,然后用
composer update --lock重生成(适合团队已约定基准分支) - 彻底清空 lock 和 vendor,用
composer update --minimal-changes重建(适合冲突严重、需最小扰动) - 绝对不要在 CI 流程里用
--ignore-platform-reqs绕过 PHP 版本检查——它不会修复依赖图,只会把问题拖到运行时报错
真正影响评估的难点,从来不是“哪些包变了”,而是“哪些约束被隐式放宽了”。比如把 "php": "^8.0" 改成 "php": ">=8.0",表面看一样,实则允许 8.99,而某个包的 conflict 规则可能只写了 ",这就埋下 runtime crash 的伏笔。


















