composer why-not 无输出通常因目标包未安装,需确保已运行 composer install、包名拼写正确且区分大小写;若在 require-dev 中还需加 --dev 参数。

composer why-not 显示“找不到包”或返回空结果
执行 composer why-not vendor/package 却没输出,通常不是命令失效,而是当前项目里根本没安装该包(哪怕 composer.json 里写了它但没 install 或 update 过)。Composer 只分析已解析进锁文件的依赖关系。
必须确保:
-
vendor/autoload.php存在,或至少运行过composer install - 目标包名拼写完全正确,包括大小写和斜杠(如
monolog/monolog不是monolog) - 如果包是
require-dev里的,需加--dev参数才生效
why-not 报出一堆冲突但看不懂哪条是关键阻塞
输出类似:
myapp/myproject dev-main requires guzzlehttp/guzzle (^7.0) symfony/console v5.4.32 requires psr/log (^1.0 || ^2.0) monolog/monolog 2.9.1 requires psr/log (^1.0 || ^2.0 || ^3.0)这类多行链式依赖时,真正卡住升级的是最上面那条「直接要求」——比如你想升
guzzlehttp/guzzle 到 ^8.0,但 myapp/myproject 的 composer.json 里硬写了 "guzzlehttp/guzzle": "^7.0",其他行只是连带影响。优先检查你自己的 composer.json 和直接依赖它的包版本约束。
为什么 --ignore platform reqs 也不让升?
有些包升级失败跟 PHP 或扩展版本有关,但 composer why-not 默认不显示平台约束冲突。它只查逻辑依赖图,不校验 php、ext-curl 等。要看到这部分原因,得换命令:
composer prohibits guzzlehttp/guzzle:8.0.0 --format=tree再配合
composer show --platform 对照当前环境。常见坑是:新版本包声明了 "php": ">=8.1",而你本地是 PHP 8.0,why-not 完全不会提这事。
想批量查多个包升级障碍,又不想反复敲命令
可以用 shell 循环快速扫描,比如检查所有 require 中的包能否升到最新稳定版:
composer show --direct --no-ansi | awk '{print }' | xargs -I {} sh -c 'echo "=== {} ==="; composer why-not {} 2>/dev/null | head -n 3'注意两点:- 输出含
Nothing to install or update表示该包已是满足约束的最新版,why-not无输出 - 某些包(如
phpunit/phpunit)可能因conflict规则被跳过,需单独用composer prohibits补查
依赖分析本质是图遍历,why-not 只展示一条路径,但真实冲突可能有好几条独立链路。如果它给出的结果和你预期不符,先用 composer depends --tree 反向查谁在引用那个旧包,比死磕 why-not 更快定位根因。










