必须用composer outdated --all、composer update --dry-run、composer audit三步交叉验证升级,否则易在ci或上线后触发call to undefined method或argumentcounterror;outdated默认只扫require包,--all才覆盖require-dev和间接依赖,!标记表示bc-breaking,但不揭示具体变更点,空输出不等于安全,audit仅比对lock中精确版本哈希与安全数据库,不查接口签名变更。

别信 composer outdated 的输出就动手升级——它只告诉你“有新版本”,不告诉你“升了会不会崩”。真正能预判风险的,是把 composer outdated --all、composer update --dry-run 和 composer audit 三者交叉比对,缺一不可。
为什么 composer outdated 单独用等于没看
它默认只扫描 composer.json 中 require 块里显式声明的包,require-dev 和大量间接依赖(比如 psr/log、symfony/polyfill-php80)全被忽略。加 --all 才能看到全貌。
- 带
!标记的行(如guzzlehttp/guzzle 7.4.5 → 7.5.0 !)不是装饰,是 Composer 从包的conflicts字段推断出存在 BC-breaking,但具体哪块破了,它不说 - 标着
not in require的包,说明没人直接声明它,得先跑composer depends vendor/package-name确认谁在拉它,再决定动不动 - 输出为空 ≠ 安全:可能是
composer.lock没提交、本地缓存过期,或包已弃用但没发新 tag - 它完全不查 CVE ——
monolog/monolog刚爆 RCE,只要没发新版,它就显示“无更新”
composer update --dry-run 看什么、怎么用才不漏关键信息
这是最接近真实升级影响的模拟,但它不执行 autoload-dump,所以类加载失败、命名空间冲突这类问题它暴露不了。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 必须加
--with-dependencies:否则像symfony/http-kernel升级时连带的psr/cache变更就看不到 - 想测多个包组合?用
composer update vendor/a vendor/b --dry-run,别直接composer update全量刷,干扰太大 - 如果项目用了
config.platform(比如锁定"php": "8.0"),得人工核对--dry-run结果里有没有包要求php:^8.2这种越界版本 - 对比
composer.lock差异时,重点关注"version"行是否跳主版本(如"version": "2.12.0"→"version": "3.0.0"),以及"source"是否变更(说明底层 Git commit 或 ZIP 包来源已不同)
composer audit 不是摆设,但得会读结果
它只比对 composer.lock 里记录的**精确版本哈希**和 Symfony 安全数据库(FriendsOfPHP/security-advisories),不是扫 vendor/ 目录,也不是读 composer.json 的模糊约束。
- 必须先运行
composer install或composer update,否则vendor/为空或哈希不匹配,audit就报 “No vulnerabilities found” - 私有包、fork 包、
path类型仓库默认跳过,除非你在composer.json里显式配了"type": "package"并提供安全元数据 - CI 中别用默认行为卡点:加
--level=high --level=critical --no-dev,避免 low 级别旧漏洞拖垮流水线 -
audit不提醒接口签名变更、方法参数加 nullable、类被删——这些只能靠测试和phpstan暴露
升级后哪些验证动作不能跳
光跑 phpunit 不够,很多问题藏在边缘路径里,且不会立刻报错。
- 检查日志:
tail -n 50 storage/logs/laravel.log(Laravel)或var/log/dev.log(Symfony),重点搜Deprecated:和Warning:——这是下个主版本就删的信号 - 验证自动加载:运行
composer dump-autoload -o,再试php -r "echo class_exists('App\Http\Controllers\HomeController') ? 'ok' : 'fail';",排除 PSR-4 映射断裂 - 抓 HTTP 响应头和状态码:某些框架升级后默认开启 CSP、修改了
X-Powered-By或强制 HTTPS 重定向,前端可能因此报 CORS 或 301 循环 - 测试失败堆栈里一旦出现
Call to undefined method或ArgumentCountError,基本可锁定是某个依赖改了契约——此时别翻 changelog,先用composer show -a vendor/package-name查它所有已发布版本的requires和conflicts,快速定位冲突源头
最容易被忽略的是:升级后没重跑 composer dump-autoload -o,导致 PSR-4 映射还是旧的;还有就是 phpunit.xml 里 bootstrap 路径写错,测试根本没加载新类,失败原因被误判为“依赖问题”。










