composer outdated --all 才能全面检查所有已安装包(含 require-dev 和传递依赖),默认命令仅扫描 require 显式声明的包,且不提示 bc-breaking 更改;带 ! 表示存在破坏性更新,需结合 --dry-run 和 audit 交叉验证风险。

直接用 composer outdated --all,别只跑默认命令——它默认漏掉 require-dev 和所有间接依赖,等于只看了半张地图。
为什么 composer outdated 默认输出不可信
默认不带参数运行 composer outdated,只会检查你 composer.json 中 require 下显式声明的包。以下三类关键包它完全不扫:
-
require-dev里的工具(比如phpunit/phpunit、phpstan/phpstan) - 传递依赖(比如
psr/log、symfony/polyfill-php81) - 被
replace或conflict隐形替换掉的包(例如某包声明"replace": {"monolog/monolog": "*"})
更危险的是:它不会标出 BC-breaking 变更。哪怕一个包从 2.x 升到 3.x,只要约束允许(如 "^2.0 || ^3.0"),它就安静地显示箭头,不加任何警告。
composer outdated --all 的真实含义和使用姿势
--all 不是“全量扫描”,而是“展示所有已安装包的可升级状态”,包括 dev 包和间接依赖。但它仍受 composer.lock 约束——锁文件里没的包,它不会凭空列出。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 加
-f json可导出结构化数据,方便脚本解析 - 加
--direct能单独过滤出你require和require-dev里直接写的包 - 输出中带
!的行(如guzzlehttp/guzzle 7.4.5 → 7.5.0 !)表示该更新含已知 BC-breaking 更改,必须查 CHANGELOG - 标着
not in require的包,说明没人显式 require 它,得先跑composer depends vendor/package-name看谁在拉它
真正能预警风险的组合动作
单靠 outdated 只能看到“能升”,看不到“升了会炸”。必须交叉验证:
-
composer outdated --all:摸清表面可升级范围 -
composer update --dry-run -v:看 Composer 实际打算怎么动——是否降级、是否触发 conflict、哪些包会被连带更新 -
composer audit:查安全漏洞,它不看版本号,只比对 FriendsOfPHP/security-advisories 数据库
注意:audit 默认不阻断执行,但返回非零退出码;CI 中应加 --format=json 并检查 critical 字段。
容易被忽略的“假过期”陷阱
有时 outdated 显示某包有新版,但实际不能升——常见原因:
- 项目设了
"minimum-stability": "dev",把dev-main当成可升级目标,但该分支不稳定且未打正式 tag -
composer.lock没提交或本地缓存过期,导致outdated读的是旧元数据 - 包已被弃用(abandoned),Packagist 页面顶部有 DEPRECATED 标识,但
outdated仍把它当正常包列出来 - 上游包在
conflict字段硬锁了你的当前版本(如"conflict": {"laravel/framework": "),而你卡在 9.x
这类情况不会报错,但硬 update 会失败。最省事的确认方式是:composer show -a vendor/package-name 查它所有版本的 requires 和 conflicts 字段。










