版本和约束#
Composer 版本 vs VCS 版本#
由于 Composer 主要用于利用 Git 等版本控制系统,因此 "版本" 这个词可能有点模棱两可。在版本控制系统的意义上,"版本" 是包含特定数据的特定文件集。在 Git 术语中,这是 "引用",或一个特定的提交,它可以由分支头或标签表示。当你在 VCS 中检出该版本时 - 例如,标签 v1.1
或提交 e35fa0d
- 你是在请求一个已知的单个文件集,并且你总是会获得相同的回显文件。
在 Composer 中,通常被非正式地称为版本的 - 也就是,在 require 行中跟在包名之后的字符串(例如,~1.1
或 1.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.0
、1.0.1
、1.0.2
、1.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 说明我们试图检出一个分支而不是标签。在上面的示例中,我们有两个版本分支:v1
和 v2
。为了让 Composer 检出其中一个分支,你必须指定一个看起来像这样的版本约束:v1.x-dev
。.x
是一个 Composer 要求的任意字符串,用于告诉它我们谈论的是 v1
分支,而不是 v1
标签(或者,你也可以将分支命名为 v1.x
而不是 v1
)。在具有版本类似名称的分支的情况下(在本例中为 v1
),你需要添加 -dev
作为后缀,而不是使用 dev-
作为前缀。
稳定性#
Composer 识别以下稳定性(按稳定性排序):dev、alpha、beta、RC 和 stable,其中 RC 代表候选版本。版本的稳定性由其后缀定义,例如版本 v1.1-BETA
的稳定性为 beta
,v1.1-RC1
的稳定性为 RC
。如果没有此类后缀,例如版本 v1.1
,则 Composer 认为该版本为 stable
。除此之外,Composer 会自动将 -dev
后缀添加到所有数字分支,并将从 VCS 仓库导入的所有其他分支名前缀为 dev-
。在这两种情况下,都会分配稳定性 dev
。
牢记这一点将有助于你理解下一节。
最低稳定性#
还有一件事会影响从库的 VCS 中检出并添加到项目中的文件:Composer 允许你指定稳定性约束来限制哪些标签被视为有效。在上面的示例中,请注意,库在最终正式发布之前发布了 1.1
版本的 beta 版本和两个候选版本。为了在运行 composer install
或 composer 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
文件中的默认版本约束。您可以调整版本约束,该工具将突出显示所有匹配的版本。
发现错字了吗?文档中有什么错误吗? 分叉并编辑 它!