composer outdated 默认仅检查 composer.json 中显式声明的包,不递归扫描间接依赖;加 --all 可查看全部已安装包,--direct 为默认行为,--no-dev 可跳过开发依赖;红、黄、无色及 ! 号分别表示主版本跃迁、补丁更新、bc-breaking 更改和当前已是最新或被锁定。

composer outdated 默认只查你亲手写的包
它不递归扫描间接依赖,比如 laravel/framework 带进来的 symfony/http-foundation,哪怕已停更两年,默认也不会出现在结果里。这不是 bug,是设计如此:只比对 composer.json 的 require 和 require-dev 区块里你显式声明的包。
常见现象是运行后输出空或寥寥几行,但项目一跑就报奇怪警告——根源往往在深层依赖没被扫到。
- 加
--all才能看到全部已安装包(含传递依赖、suggest里的可选包) - 加
--direct(默认行为)可确认哪些是你自己 require 的旧包,适合快速判断是否该升主框架 - 加
--no-dev跳过开发依赖,减少干扰
颜色和 ! 号才是关键信号
终端里红、黄、无色不是装饰,是风险等级提示:
-
红色行(如
symfony/console v5.4.32 → v6.0.19):主版本跃迁,极可能破坏兼容性 -
黄色行(如
guzzlehttp/guzzle v7.8.1 → v7.8.2):仅补丁更新,大概率安全 - 带
!的行(如doctrine/dbal 3.6.4 → 3.7.0 !):Composer 自动识别出 BC-breaking 更改,哪怕只是次版本也得查 CHANGELOG - 无色 = 当前版本已是约束范围内最新,或被固定版本锁死(如
"phpunit/phpunit": "9.5.10")
为什么有时候 outdated 没输出或报错
卡点通常不在命令本身,而在环境状态:
-
Could not find package lock file:composer.lock不存在或损坏,先运行composer install或composer update --lock - 没反应或卡住几秒退出:网络问题(如无法访问 packagist),试
composer clear-cache或换镜像源 - 输出为空但你知道该有更新:检查是否用了
minimum-stability限制,或私有仓库配置失效(拼写错误、URL 不可达) - 某些包没显示:PHP 版本不匹配导致被自动过滤(如
composer config platform.php和实际php -v不一致)
真正要升级前必须验证的三件事
outdated 只告诉你“有哪些可升”,不保证能升成功:
- 查对应包的 CHANGELOG 或 GitHub Releases,重点扫
Breaking Changes和Deprecations—— 尤其注意你代码里是否用了被标记为 deprecated 的方法 - 运行
composer update --dry-run vendor/package,看依赖树是否引入意外冲突(比如某个次要包突然要求更高 PHP 版本) - 如果项目有测试,至少跑一遍;很多“兼容”只是 API 层面的,行为细节可能已变
最麻烦的从来不是发现过期,而是发现之后不知道该不该升、能不能升、升完会不会崩。每次 outdated 的输出,本质是一张待验证的风险清单,不是升级任务单。











