composer outdated 默认仅检查显式声明的直接依赖,间接依赖需加 --all;安全漏洞须用 composer audit,而非 outdated;版本颜色和 ! 符号标识风险等级与 BC-breaking 更改。

composer outdated 默认只看直接依赖,不是“所有包”
执行 composer outdated 后发现输出空,或只有两三个包,别急着认为项目干净——它默认只检查 composer.json 中 require 和 require-dev 里**显式声明的包**,像 symfony/console 拉进来的 psr/log 这类间接依赖,压根不会出现。
- 想看全部(含子依赖),必须加
--all:composer outdated --all - 但
--all结果噪音大,常混入几十个稳定无更新的包;建议搭配--format=json+jq过滤,比如只抓有major升级风险的:composer outdated --all --format=json | jq -r '.packages[] | select(.latest-status == "major") | "\(.name) \(.installed.version) → \(.latest.version)"' -
--direct和不加参数效果一样,只是语义更清楚;它**自动忽略require-dev**,真要查测试依赖,得额外加--dev
颜色和 ! 符号才是升级前必须看懂的信号
终端里红/黄/绿不是装饰——它们直接对应风险等级。黄色箭头(→)右侧版本是「满足你当前版本约束」的新版,比如你写 "monolog/monolog": "^2.8",它标出 2.9.0 是黄色,说明能安全升;但若标成红色,代表 composer.lock 里锁的版本比远程最新版旧,composer update 没跑过。
- 带
!的行(如doctrine/dbal 3.6.4 → 3.7.0 !)是高危提示:新版本含 BC-breaking 更改,composer已从其conflict字段识别到,但没拦你——必须去查 CHANGELOG - 版本号后标
(stable)/(RC)是稳定性提示,minimum-stability设为stable时,RC版本根本不会出现在推荐列表里 - 看到
not in require别跳过:这表示它是间接依赖,没人显式管它,升级前先用composer depends vendor/package看谁在用它
安全漏洞不能靠 outdated 查,得用 audit
composer outdated 不检测 CVE,也不查已知漏洞。它只对比版本号,哪怕某个包刚爆了 RCE,只要没发新版,它就显示“无更新”。
- 查真实安全风险,用
composer audit(Composer ≥ 2.5.0);它读取 Packagist 官方security-advisories数据库 -
composer outdated --security-only是快捷入口,但前提是已运行过composer audit或启用security-advisories插件,否则会静默返回空 - 注意:它不扫描
require-dev中的包(除非加--dev),而phpunit、roave/security-advisories这类测试/安全工具一旦有漏洞,CI 环境可能被当跳板利用
本地结果和 CI 不一致?先盯住缓存和镜像源
你在本地跑 composer outdated 显示有 guzzlehttp/guzzle 可升到 7.9.0,CI 却说“无更新”,大概率不是命令错了,而是环境元数据不同步。
- 检查是否用了国内镜像(如阿里云、华为云),它们同步延迟几小时到一天很常见;临时切回官方源验证:
composer config repo.packagist.org https://packagist.org - 本地缓存可能过期:
composer clear-cache再试;CI 脚本里建议加这步,避免因缓存导致漏报 - CI 使用的老版 Composer(如 2.0.x)不支持
--security-only或--major-only,会直接忽略参数或报错,得统一升级 Composer 版本
真正麻烦的不是命令怎么写,而是过期包背后牵扯的兼容性链和安全上下文——一个 ! 标记,可能意味着你要重写三处调用逻辑;一个 not in require,可能指向某个早已弃用的子依赖。别信“一键升级”,先看清它动的是哪根神经。










