composer outdated 仅比对 composer.lock 与 Packagist 版本,不主动通知;它列出满足 composer.json 约束的可升级版本,需配合 --direct --minor-only --no-dev 聚焦关键依赖,用退出码(有更新返回3)驱动 CI,且须结合 composer audit 防 CVE 漏洞。

composer outdated 不是“提醒工具”,它只比对锁文件和 Packagist
它不推送通知、不发邮件、不写日志,也不在你 push 前弹窗——所谓“提醒”,其实是你把它放进脚本或 CI 后自己定义的行为。命令本身只做一件事:读取 composer.lock,查 Packagist 上每个已安装包的最新稳定版,然后列出「当前装的版本」和「在 composer.json 约束下允许升到的最高版本」之间的差距。
常见错误现象:
- 刚改完
composer.json加了"laravel/framework": "^10.0",但composer outdated没显示 Laravel 更新 → 因为没运行composer install或composer update,composer.lock还是旧的,比对基础不存在 - 输出里某包标红(如
symfony/console6.2.0 → 7.0.0),但你明明写了"^6.0"→ 实际是composer.lock里还存着 6.2.0,而 Packagist 上 7.0.0 已发布,但它**不满足**你的^6.0约束,所以这行根本不会出现(标红的是满足约束的 minor/major 升级)
怎么只看真正该管的依赖:--direct --minor-only --no-dev
默认 composer outdated 会扫整个依赖树,包括 monolog/monolog 的子依赖 psr/log,几百行根本没法盯。生产项目真正要关注的,只有你亲手写进 composer.json 的那几十个包。
-
--direct:跳过所有间接依赖,只列require和require-dev里直写的包 -
--minor-only:过滤掉 major 升级(如 5.x → 6.x),只保留兼容性风险低的 minor(5.4 → 5.5)和 patch(5.4.1 → 5.4.2)更新 -
--no-dev:CI 或线上环境无需检查phpunit、phpstan这类开发依赖,加它能减少干扰
组合起来就是最实用的一行:composer outdated --direct --minor-only --no-dev
CI 中用退出码判断是否“有更新”,别靠肉眼扫
composer outdated 的退出码不是摆设:有符合条件的更新时返回 3,无更新返回 0。这比解析 JSON 或 grep 文本可靠得多。
- 想让 CI 发现可升级包时仅警告(继续跑后续步骤):
composer outdated --direct --minor-only --no-dev --quiet || echo "⚠️ 存在可升级依赖" - 想强制阻断发布(比如灰度环境要求所有直接依赖必须是小版本最新):
composer outdated --direct --minor-only --no-dev --quiet && echo "✅ OK" || (echo "❌ 需升级依赖后重试"; exit 1) - 注意:
--quiet是关键——去掉它,命令会输出表格,CI 日志里混着彩色 ANSI 字符,容易导致解析失败
安全更新不能只靠 outdated,必须配 composer audit
composer outdated 可能显示 guzzlehttp/guzzle 7.5.0 → 7.8.1,看起来只是补丁升级;但如果你漏了 composer audit,就可能不知道 7.5.0 其实含 CVE-2023-38922(HTTP 请求走私漏洞),而 7.8.1 才修复它。
-
composer audit查的是 Packagist 安全公告数据库,不是版本号,它能明确告诉你哪个 CVE 影响哪个已安装版本 - 它默认检查全部依赖(含
require-dev),加--no-dev可跳过开发工具 - 旧版 Composer(roave/security-advisories 锁死已知危险版本
真正容易被忽略的是:很多人在 CI 里只跑 outdated 就以为“没高危包”,结果上线后被扫出漏洞——outdated 不负责安全,audit 才是守门人。


















