首页 > 解决方案 > composer require 如何解析项目中已有的依赖包?

问题描述

当使用composer require将新包添加到现有项目时,composer 如何协调作为现有项目和新需要的包的依赖项的包的版本?

假设我有一个由包 A 组成的项目,并且包 A 依赖于包 B,版本约束为 ~1.0。在安装时,包 B 的当前版本是 1.1,所以这就是安装并写入锁定文件的内容。

然后稍后我想将包 C 添加到我的项目中。包 C 也依赖于包 B,但版本约束 >=1.0。在添加包 C 时,包 B 的最新版本是 1.2。

当我做 acomposer require C/C时,包 B 会发生什么?根据原始安装和锁定文件,B 会保持在 1.1 吗?或者B会更新到最新版本(1.2)吗?

再次考虑上述情况,但唯一的区别是包 C 需要版本约束为 >1.1.3 的包 B。这次会有什么行为?composer会拒绝安装新的包C,因为依赖B的版本约束会与锁文件冲突吗?还是 composer 会将包 B 更新到最新版本(1.2)?

标签: composer-php

解决方案


我现在已经成功地测试了我上面描述的两种场景,作曲家的行为实际上相当不错。

如果您将包添加到现有项目(具有现有锁定文件)composer require <vendor>/<package>,即使更新版本已发布,composer 也会维护锁定文件中列出的任何依赖项的锁定版本。所以在我上面的例子中,包 B 保持在 1.1 版本,因为这是在锁定文件中定义的。

如果,当您需要一个新包时,该包具有当前安装的该依赖项的版本无法满足的依赖项约束,即使该依赖项的较新版本与原始 composer.json 兼容,则 composer 给出以下错误:

Your requirements could not be resolved to an installable set of packages.
Problem 1
Can only install one of: vendor/b[v1.2, v1.1].
vendor/c v1.1 requires vendor/b ~1.2 -> satisfiable by vendor/b[v1.2].
Installation request for vendor/c ^1.1 -> satisfiable by vendor/c[v1.1].
Installation request for vendor/b (locked at v1.1, required as ~1.0) -> satisfiable by vendor/b[v1.1].

我认为关键位在哪里locked at v1.1

正如@Adam 所建议的那样,执行 acomposer require似乎隐含地执行composer updatea ,但此更新似乎受到现有 composer.lock 文件的限制。composer require <vendor>/<package>只做 a和 acomposer require <vendor>/<package> --no-update后跟 a是有区别的composer update。在 arequire --no-update后跟 an的情况下update,行为会有所不同,所有包都是从头开始解析的(没有锁定文件的引用),并且安装了最新版本的包。

以上所有内容均针对 composer 1.10 进行了测试。由于结果似乎合理且经过深思熟虑,我没有理由认为它会在 2.x 中发生变化,但我没有对此进行测试。


推荐阅读