<p>带 表示该包版本低于最新兼容版本,不带 表示已为最新或使用 dev 分支等 Composer 不提示升级的情形。</p>

composer outdated 显示的包为什么有的带 * 有的不带
带 * 表示该包在 composer.json 中声明了版本约束(比如 "monolog/monolog": "^2.0"),但当前已安装版本**低于最新兼容版本**;不带 * 的包,要么是已为最新,要么是你用 dev-master 或 dev-main 这类开发分支,Composer 默认不将其标记为“可更新”——它认为你在主动追踪开发线,不提示升级。
常见错误现象:composer outdated 没列出某个明显有新版的包,其实是因为你锁定了 dev- 分支或用了 ^ 以外的写法(如 ~1.2),导致 Composer 认为当前版本仍在允许范围内。
- 检查是否用了
dev-前缀:这类包不会标*,但实际可能早已落后几个 commit - 注意
composer outdated --direct只看根依赖,--all才显示所有依赖树中的过时包(含子依赖) -
composer outdated --minor-only只提示小版本更新(跳过主版本变更),适合不想破坏兼容性的场景
执行 composer outdated 后怎么安全升级
它只是个查看命令,不修改任何文件。真正升级要靠 composer update,但直接全量更新风险高——尤其当多个包同时升主版本时,容易触发冲突或行为变更。
使用场景:日常维护中,建议只升级明确需要的包,而不是一次全更。
- 升级单个包:
composer update vendor/package-name(例如composer update guzzlehttp/guzzle) - 升级某类包(如仅 dev 依赖):
composer update --dev - 避免意外升主版本:
composer update --with-dependencies会连带更新其依赖,但加上--dry-run先预览变化 - 升级前务必确认
composer.lock已提交,否则回滚困难
为什么 composer outdated 不显示某些包的更新(比如 Laravel 的子包)
Laravel 生态里很多包(如 laravel/framework、laravel/tinker)默认通过 replace 或 conflict 规则绑定主框架版本,Composer 会跳过它们的独立版本检查——它认为“只要 laravel/framework 版本对,其他就该匹配”。所以即使 laravel/pint 有 v1.13 新版,只要你的 laravel/framework 锁在 v10.x,它就不会出现在 outdated 列表里。
性能影响:这种隐式约束让 outdated 执行更快,但也掩盖了部分可选更新。
- 想强制检查所有包(包括被
replace掩盖的):composer outdated --all --direct - 留意
outdated输出里的allowed列:如果显示None,说明当前版本已超出composer.json约束范围,但 Composer 没自动降级——这时得手动composer require vendor/pkg:version - 某些包(如
phpunit/phpunit)若设为require-dev且未启用--dev,默认不参与检查
CI/CD 中怎么用 composer outdated 做自动检测
它本身不报错,所以直接用在脚本里无法触发失败。必须配合 --format=json 解析输出,再判断是否有带 * 的条目。
常见错误现象:写成 composer outdated && echo "OK",结果不管有没有更新都执行成功。
- 推荐做法:
composer outdated --direct --json | jq -e '.packages[] | select(.latest != .installed and .latest != null) | length > 0' > /dev/null || echo "No updates"(需装jq) - 更轻量替代:
composer outdated --direct --no-ansi | grep '\* $' | head -1,有输出即存在可更新包 - 注意
--no-ansi避免颜色字符干扰解析;--quiet会抑制所有输出,连 JSON 都不打印,慎用 - CI 中建议加
--ignore-platform-reqs避免因 PHP 版本差异误报(但上线前仍需在目标环境验证)
最常被忽略的是:它不检查 lock 文件是否和 json 一致——composer install 时若发现 lock 与 json 不匹配,照样会重装,哪怕 outdated 显示“无更新”。所以定期 composer update --lock 保持两者同步,比盯着 outdated 更关键。










