composer outdated 检查 composer.lock 中已安装版本与 packagist 上满足 composer.json 版本约束的最高稳定版之间的差异,仅显示兼容范围内可升级的版本,不提示突破约束的新大版本。

composer outdated 命令到底检查什么?
composer outdated 不是“查有没有新版本”,而是查“有没有满足你当前版本约束的新版本”。
比如你在 composer.json 里写的是 "monolog/monolog": "^2.0",那它只关心 2.x 范围内的最新版(如 2.10.0),不会告诉你 3.0.0 已发布——哪怕 3.0.0 更安全、功能更强。
- 它比对的是
composer.lock中记录的已安装版本 和 Packagist 上符合当前约束的最高稳定版 - 默认忽略
dev-分支、beta、rc版本,除非加--all - 如果某个包被
composer.lock锁死在旧版,但该旧版仍满足composer.json的约束(例如锁在 2.4.0,约束仍是^2.0),它不会显示为 outdated——这是最常让人误以为“没更新”却实际有更高兼容版可升的情况
怎么只看自己写的 require 里的包?
用 composer outdated --direct。
这能过滤掉所有间接依赖(比如 symfony/console 引入的 psr/log),只聚焦你亲手写进 composer.json 的那些包。
-
--direct看的是require和require-dev顶层声明,不看子依赖树 - 但它不会跳过已被 lock 文件固定住的包:如果某个直接依赖被锁在 1.2.0,而约束是
^1.0,且 1.9.0 是兼容最高版,它就会显示出来 - 想排除
require-dev包?加--no-dev:composer outdated --direct --no-dev
为什么有时候明明有新版,却不出现在 outdated 列表里?
常见原因就这几个:
-
composer.lock还没刷新远程元数据:运行一次composer update --dry-run --no-install再试 - 版本约束太宽或太窄:比如写了
"^2.4"却想升到 3.0,得先改composer.json,再加--all才能看到提示 - 当前 stability 设置限制了预发布版:如果
"minimum-stability": "stable",那v4.0.0-RC1就不会被当作“可用更新” - 包本身被标记为
"replace"或"provide",Composer 会跳过比对
想安全升级,光看 outdated 还不够
composer outdated 是诊断工具,不是升级开关。它告诉你“能升”,但不保证“升了不崩”。
- 看到想升的包,别急着
composer update全量更新:先用composer update vendor/package-name单点升级 - 想连带更新它的子依赖?加
--with-dependencies,但要小心——可能把其他包也拖进大版本 - 需要确认变更范围?加
--dry-run:composer update monolog/monolog --dry-run - 输出 JSON 供 CI 自动解析?加
--format=json,但注意它默认仍只输出“可安全升”的包,不是全部
真正容易被忽略的点是:outdated 的结果受 composer.lock 缓存影响,有时本地没同步远程元数据,就会漏掉本该出现的更新项;定期跑一遍 composer update --dry-run --no-install,比什么都管用。










