composer why-not 和 composer prohibits 用于精准定位版本安装失败原因:why-not 列出直接冲突的包及其约束,prohibits 查某精确版本被哪些包明确排除;二者均不处理间接依赖。

composer why-not 和 composer prohibits 怎么用才准
这两个命令不是“查谁用了它”,而是定位“为什么某个版本装不上”。比如你想升 guzzlehttp/guzzle 到 7.4.0,但 composer require guzzlehttp/guzzle:7.4.0 报错,直接运行:
composer why-not guzzlehttp/guzzle:7.4.0
它会列出所有阻塞该版本的包及其约束条件,比如:myapp/core requires guzzlehttp/guzzle:^6.5,或者 symfony/http-client requires guzzlehttp/guzzle:~6.0。注意:它不显示间接路径,只显示**直接声明冲突的包**。
composer prohibits 更进一步,可查某版本被哪些包明确排除:
composer prohibits guzzlehttp/guzzle:7.4.0
常见错误是把参数写成 guzzlehttp/guzzle:^7 —— 这会被解析为“匹配任意 ^7 版本”,结果返回空;必须写精确版本号(如 7.4.0)或带等号的表达式(如 =7.4.0)。
composer update vendor/a vendor/b --with-dependencies 的边界在哪
这个命令只重算你列出来的包 + 它们在 composer.json 中 require 的一级依赖,不会动其他包的子依赖。例如:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
composer update monolog/monolog guzzlehttp/guzzle --with-dependencies- 会更新
monolog/monolog、guzzlehttp/guzzle本身 - 也会更新它们各自
require的psr/log、psr/http-message等直系依赖 - 但不会碰
symfony/console,哪怕它被laravel/frameworkrequire,只要没出现在命令行列表里
容易踩的坑:
- 包名必须写全,不能加引号:
composer update "monolog/monolog"❌,会触发模糊匹配逻辑,可能升级一堆无关包 - 如果两个包都 require 同一个库但版本不交叠(如一个要
^1.0,另一个要^2.0),命令会失败,而不是自动选中间版——Composer 不做“折中”,只找满足全部约束的解 - 执行后务必检查
composer.lock变更范围,尤其关注 PHP 扩展要求是否被新版本抬高(比如新guzzle要求ext-curl >= 8.0)
多包开发时 composer.lock 必须统一维护
跨多个 Composer 包协作(比如 vendor/myorg/core 和 vendor/myorg/api 同时被主项目 require)时,composer.lock 不是“可选文件”,而是唯一真相源。不同团队各自 update 会导致 lock 文件差异,进而引发:
- CI 构建时依赖版本不一致,测试通过但线上报
Class not found -
composer install在不同机器上还原出不同vendor/结构 - 本地
composer update后提交了部分 lock 变更,别人git pull后install失败
实操建议:
- 所有包的
composer.json中禁止写死"minimum-stability": "dev"或"prefer-stable": false,避免引入不稳定分支 - 主项目每次
composer update后,必须git add composer.lock并合入主干 - 内部包发布新版本前,先在主项目中验证
composer update vendor/myorg/core是否能成功,再打 tag
版本演进不是靠自动猜,而是靠显式约束联动
没有“智能升级助手”能绕过 composer.json 的约束逻辑。所谓“自动版本演进”,本质是你写的约束是否留有空间:
- 写
"monolog/monolog": "^1.25",它就能随生态升到1.27;写死"1.25.0",就永远卡住 - 如果
myorg/corerequire"guzzlehttp/guzzle": "^7.0",而myorg/apirequire"^6.5",那主项目想同时用两者,就必须让其中一个放宽约束,否则无解 - 不要依赖
--with-all-dependencies来“扫清障碍”——它只是扩大求解范围,不改变约束本身;若约束之间根本无交集,它只会花更长时间报同样错
真正需要人工判断的是:哪个包的约束该松、哪个该紧、哪个该换。自动工具只能告诉你“哪里堵了”,不能替你决定“往哪修路”。

















