composer outdated 默认只显示直接依赖的过期包,不包含子依赖;加 --all 可查看所有依赖,--direct 显式指定直接依赖,--minor-only 或 --patch-only 限制更新类型。

composer outdated 会显示哪些包过期
默认只列出直接依赖(require 和 require-dev 中声明的包),不递归检查子依赖。比如你装了 laravel/framework,它依赖的 symfony/http-foundation 即使有新版也不会出现在列表里——除非你显式 require 过它。
常见错误现象:运行 composer outdated 后发现“没几个包”,但实际项目跑着总报奇怪警告,其实是间接依赖在作祟。
- 加
--all参数才能看到所有依赖(含传递依赖),但输出会很长,建议搭配grep或head -20 - 加
--direct(默认行为)可确认哪些是你亲手写进composer.json的旧包 - 加
--minor-only或--patch-only可限制只看小版本或补丁更新,避免被主版本升级吓到
怎么判断某个包该不该升级
不是所有标红的“outdated”都值得立刻动。关键看三件事:版本号变化类型、是否在 composer.json 中锁死、有没有已知兼容问题。
例如 monolog/monolog 显示从 2.9.1 → 3.5.0,这就是主版本跃迁(2→3),大概率有 BC break;而 phpunit/phpunit 从 10.4.2 → 10.5.1 就只是补丁更新,通常安全。
- 检查
composer.json里该包的约束符:用^一般能自动吃到小版本,用~或固定版本号就得手动改 - 看包的 CHANGELOG 或 GitHub Releases,重点扫 “Breaking Changes” 小节
- 如果项目用了
composer.lock,outdated显示的是 lock 文件里的版本 vs 当前 Packagist 最新版本,不是本地安装版本
为什么 composer outdated 没反应或报错
最常见原因是没在项目根目录执行,或者 composer.json 根本不存在。其次是网络或 Packagist 访问异常,导致元数据拉不到。
错误信息如 Could not fetch packages information, aborting. 或直接卡住几秒后退出,基本是网络问题;而 No composer.json found in the current directory 就是路径错了。
- 先确认当前路径下有
composer.json,且不是子目录(比如误进了vendor/) - 临时换镜像源试试:
composer config repo.packagist composer https://packagist.phpcomposer.com(国内常用) - 加
-v参数看详细日志,能快速定位是 DNS、SSL 还是超时 - 某些 CI 环境禁用了 HTTPS,需设
export COMPOSER_DISABLE_TLS=1(不推荐长期用)
想批量检查多个项目怎么办
没有内置命令,但可以用 shell 脚本绕过。核心思路是 cd 进每个项目、执行 composer outdated --direct --no-ansi、提取关键行。
注意别用 composer global outdated——它查的是全局安装的包(如 laravel/installer),和当前项目无关,容易混淆。
- 简单脚本示例:
for dir in ./project-a ./project-b; do echo "== $dir =="; (cd "$dir" && composer outdated --direct --no-ansi 2>/dev/null | grep -E '^[a-z]'); done
-
--no-ansi避免颜色控制符污染管道输出 - 过滤用
grep -E '^[a-z]'是因为真正过期包行首是包名(小写字母开头),标题行和空行会被筛掉 - 如果项目多、更新频,建议把结果写入时间戳文件,方便比对
真正麻烦的永远不是“怎么看”,而是“看懂之后要不要升、怎么升得稳”。尤其是 dev-main 或 dev-develop 这类分支别名,outdated 会把它标成“远落后”,但其实你就是故意钉在开发版上——这种得靠人眼判断,工具帮不上忙。










