版本和约束#

Composer 版本 vs VCS 版本#

由于 Composer 主要用于利用 Git 等版本控制系统,因此 "版本" 这个词可能有点模棱两可。在版本控制系统的意义上,"版本" 是包含特定数据的特定文件集。在 Git 术语中,这是 "引用",或一个特定的提交,它可以由分支头或标签表示。当你在 VCS 中检出该版本时 - 例如,标签 v1.1 或提交 e35fa0d - 你是在请求一个已知的单个文件集,并且你总是会获得相同的回显文件。

在 Composer 中,通常被非正式地称为版本的 - 也就是,在 require 行中跟在包名之后的字符串(例如,~1.11.2.*) - 实际上更具体地称为版本约束。Composer 使用版本约束来确定应该检出 VCS 中的哪些引用(或者在静态维护的库的情况下验证给定库是否可接受,该库在 composer.json 中具有 version 规范)。

VCS 标签和分支#

对于以下讨论,让我们假设以下示例库仓库

~/my-library$ git branch
v1
v2
my-feature
another-feature
~/my-library$ git tag
v1.0
v1.0.1
v1.0.2
v1.1-BETA
v1.1-RC1
v1.1-RC2
v1.1
v1.1.1
v2.0-BETA
v2.0-RC1
v2.0
v2.0.1
v2.0.2

标签#

通常,Composer 处理标签(而不是分支 - 如果你不知道这意味着什么,请阅读关于 版本控制系统 的内容)。当你编写版本约束时,它可能引用特定标签(例如,1.1),或者它可能引用有效标签范围(例如,>=1.1 <2.0~4.0)。为了解析这些约束,Composer 首先要求 VCS 列出所有可用的标签,然后基于这些标签创建一个内部可用版本列表。在上面的示例中,Composer 的内部列表包括版本 1.01.0.11.0.21.1 的 beta 版本、1.1 的第一个和第二个候选版本、最终发布版本 1.1 等......(请注意,Composer 会自动删除实际标签名称中的 'v' 前缀以获得有效的最终版本号。)

当 Composer 从你的 VCS 获得了一个完整的可用版本列表后,它就会找到匹配你项目中所有版本约束的最高版本(其他包可能需要比你更具体的库版本,因此它选择的版本可能并不总是最高可用的版本),然后它会下载该标签的压缩存档,并在你 vendor 目录的正确位置解压缩。

分支#

如果你希望 Composer 检出一个分支而不是标签,你需要使用特殊的 dev-* 前缀(或有时是后缀;请参见下文)来指向它。如果你正在检出一个分支,则假定你想要在该分支上工作,并且 Composer 会将仓库克隆到你的 vendor 目录的正确位置。对于标签,它会复制正确文件,而不会实际克隆仓库。(你可以使用 --prefer-source 和 --prefer-dist 修改此行为,请参见 安装选项。)

在上面的示例中,如果你想要检出 my-feature 分支,你将在 require 子句中指定 dev-my-feature 作为版本约束。这将导致 Composer 将 my-library 仓库克隆到我的 vendor 目录中,并检出 my-feature 分支。

当分支名称看起来像版本时,我们需要为 Composer 说明我们试图检出一个分支而不是标签。在上面的示例中,我们有两个版本分支:v1v2。为了让 Composer 检出其中一个分支,你必须指定一个看起来像这样的版本约束:v1.x-dev.x 是一个 Composer 要求的任意字符串,用于告诉它我们谈论的是 v1 分支,而不是 v1 标签(或者,你也可以将分支命名为 v1.x 而不是 v1)。在具有版本类似名称的分支的情况下(在本例中为 v1),你需要添加 -dev 作为后缀,而不是使用 dev- 作为前缀。

稳定性#

Composer 识别以下稳定性(按稳定性排序):dev、alpha、beta、RC 和 stable,其中 RC 代表候选版本。版本的稳定性由其后缀定义,例如版本 v1.1-BETA 的稳定性为 betav1.1-RC1 的稳定性为 RC。如果没有此类后缀,例如版本 v1.1,则 Composer 认为该版本为 stable。除此之外,Composer 会自动将 -dev 后缀添加到所有数字分支,并将从 VCS 仓库导入的所有其他分支名前缀为 dev-。在这两种情况下,都会分配稳定性 dev

牢记这一点将有助于你理解下一节。

最低稳定性#

还有一件事会影响从库的 VCS 中检出并添加到项目中的文件:Composer 允许你指定稳定性约束来限制哪些标签被视为有效。在上面的示例中,请注意,库在最终正式发布之前发布了 1.1 版本的 beta 版本和两个候选版本。为了在运行 composer installcomposer update 时接收这些版本,我们必须明确告诉 Composer 我们允许候选版本和 beta 版本(以及 alpha 版本,如果我们想要它们)。这可以通过在 composer.json 中使用项目范围的 minimum-stability 值或在版本约束中使用 "稳定性标记" 来完成。在 模式页面 上阅读更多信息。

编写版本约束#

现在你已经了解了 Composer 如何看待版本,让我们来谈谈如何为项目依赖项指定版本约束。

精确版本约束#

你可以指定包的精确版本。这将告诉 Composer 只安装此版本。如果其他依赖项需要不同的版本,求解器最终会失败并中止任何安装或更新过程。

示例:1.0.2

版本范围#

通过使用比较运算符,你可以指定有效版本的范围。有效的运算符是 >>=<<=!=

你可以定义多个范围。用空格 ( ) 或逗号 (,) 分隔的范围将被视为逻辑 AND。双竖线 (||) 将被视为逻辑 OR。AND 的优先级高于 OR。

注意:在使用无界范围时要小心,因为你最终可能会意外安装破坏向后兼容性的版本。为了安全起见,请考虑使用 插入符号 运算符。

注意:在较早版本的 Composer 中,单竖线 (|) 是逻辑 OR 的推荐替代方案。因此,为了向后兼容,单竖线 (|) 仍然被视为逻辑 OR

示例

  • >=1.0
  • >=1.0 <2.0
  • >=1.0 <1.1 || >=1.2

连字符版本范围 (-)#

版本的包含集合。右侧的局部版本包括使用通配符完成。例如,1.0 - 2.0 等效于 >=1.0.0 <2.1,因为 2.0 变成 2.0.*。另一方面,1.0.0 - 2.1.0 等效于 >=1.0.0 <=2.1.0

示例:1.0 - 2.0

通配符版本范围 (.*)#

你可以使用 * 通配符指定模式。1.0.* 等效于 >=1.0 <1.1

示例:1.0.*

下一个重大版本运算符#

波浪号版本范围 (~)#

~ 运算符最好通过示例来解释:~1.2 等效于 >=1.2 <2.0.0,而 ~1.2.3 等效于 >=1.2.3 <1.3.0。正如你所看到的,它主要用于遵守 语义版本控制 的项目。一个常见的用法是标记你依赖的最小次要版本,例如 ~1.2(允许任何直到但并不包括 2.0 的版本)。因为理论上直到 2.0 之前不应该有任何向后兼容性问题,所以这很有效。另一种看待它的方式是,使用 ~ 指定了最小版本,但允许指定的最后一位数字增加。

示例:~1.2

注意:虽然 2.0-beta.1 严格来说在 2.0 之前,但 ~1.2 这样的版本约束不会安装它。如上所述,~1.2 仅意味着 .2 可以更改,但 1. 部分是固定的。

注意:~ 运算符在针对主版本号的行为方面有一个例外。这意味着例如 ~1~1.0 相同,因为它不会允许主版本号增加,从而试图保持向后兼容性。

插入符号版本范围 (^)#

^ 运算符的行为非常相似,但它更严格地遵循语义版本控制,并且始终允许非破坏性更新。例如,^1.2.3 等效于 >=1.2.3 <2.0.0,因为直到 2.0 的所有版本都不应破坏向后兼容性。对于 1.0 之前的版本,它也具有安全意识,将 ^0.3 视为 >=0.3.0 <0.4.0,并将 ^0.0.3 视为 >=0.0.3 <0.0.4

这是编写库代码时推荐使用的运算符,以实现最大互操作性。

示例:^1.2.3

注意:如果你在 Windows 上使用 PowerShell,则在作为 CLI 上的参数使用插入符号时(例如在使用 composer require 命令时)必须对其进行转义。你必须使用四个连续的插入符号运算符,例如 ^^^^1.2.3,以确保插入符号运算符被正确地传递给 Composer。

稳定性约束#

如果你使用的是没有明确定义稳定性的约束,Composer 会在内部默认使用 -dev-stable,具体取决于使用的运算符。这会透明地发生。

如果你希望在比较中只明确考虑稳定版本,请添加后缀 -stable

示例

约束 内部
1.2.3 =1.2.3.0-stable
>1.2 >1.2.0.0-stable
>=1.2 >=1.2.0.0-dev
>=1.2-stable >=1.2.0.0-stable
<1.3 <1.3.0.0-dev
<=1.3 <=1.3.0.0-stable
1 - 2 >=1.0.0.0-dev <3.0.0.0-dev
~1.3 >=1.3.0.0-dev <2.0.0.0-dev
1.4.* >=1.4.0.0-dev <1.5.0.0-dev

但是,为了允许各种稳定性,而不在约束级别强制执行它们,你可以使用 稳定性标记,例如 @<stability>(例如,@dev),让 Composer 知道可以在与你的默认 minimum-stability 设置不同的稳定性中安装给定包。所有可用的稳定性标记都列在 模式页面 上的 minimum-stability 部分。

总结#

"require": {
    "vendor/package": "1.3.2", // exactly 1.3.2

    // >, <, >=, <= | specify upper / lower bounds
    "vendor/package": ">=1.3.2", // anything above or equal to 1.3.2
    "vendor/package": "<1.3.2", // anything below 1.3.2

    // * | wildcard
    "vendor/package": "1.3.*", // >=1.3.0 <1.4.0

    // ~ | allows last digit specified to go up
    "vendor/package": "~1.3.2", // >=1.3.2 <1.4.0
    "vendor/package": "~1.3", // >=1.3.0 <2.0.0

    // ^ | doesn't allow breaking changes (major version fixed - following semver)
    "vendor/package": "^1.3.2", // >=1.3.2 <2.0.0
    "vendor/package": "^0.3.2", // >=0.3.2 <0.4.0 // except if major version is 0
}

测试版本约束#

您可以使用 semver.madewithlove.com 测试版本约束。填写一个包名,它将自动填充 Composer 会添加到您的 composer.json 文件中的默认版本约束。您可以调整版本约束,该工具将突出显示所有匹配的版本。

发现错字了吗?文档中有什么错误吗? 分叉并编辑 它!