版本和约束
Composer版本与版本控制系统版本
Section titled “Composer版本与版本控制系统版本”由于Composer在很大程度上倾向于使用像git这样的版本控制系统,因此“版本”一词可能会有些模糊。在版本控制系统的意义上,“版本”是包含特定数据的一组特定文件。在git术语中,这是一个“引用”,或者说是一个特定的提交,它可以由分支的HEAD或标签来表示。当你在版本控制系统中检出那个版本时——例如,标签v1.1或提交e35fa0d——你请求的是一组单一的、已知的文件,并且你总会得到相同的文件。
在Composer中,通常被随意称为版本的东西——也就是require行中包名称后面的字符串(例如,~1.1或1.2.*)——实际上更具体地说是版本约束。Composer使用版本约束来确定它应该从版本控制系统(VCS)中检出哪些引用(或者在静态维护的库的情况下,验证给定的库是否符合要求,这类库在composer.json中有version规范)。
VCS标签和分支
Section titled “VCS标签和分支”在接下来的讨论中,我们假设存在以下示例库存储库:
~/my-library$ git branchv1v2my-featureanother-feature~/my-library$ git tagv1.0v1.0.1v1.0.2v1.1-BETAv1.1-RC1v1.1-RC2v1.1v1.1.1v2.0-BETAv2.0-RC1v2.0v2.0.1v2.0.2通常情况下,Composer 处理的是标签(而非分支——如果你不清楚这是什么意思,请查阅版本控制系统相关内容)。当你编写版本约束时,它可能引用特定的标签(例如1.1),也可能引用有效的标签范围(例如>=1.1 <2.0或~4.0)。为了解决这些约束,Composer 首先会请求版本控制系统列出所有可用的标签,然后根据这些标签创建一个内部的可用版本列表。在上述示例中,Composer 的内部列表包括版本1.0、1.0.1、1.0.2、1.1的测试版、1.1的第一个和第二个候选发布版、最终发布版本1.1等等……(请注意,Composer 会自动移除实际标签名称中的“v”前缀,以获得有效的最终版本号。)
当Composer从你的版本控制系统(VCS)获取到完整的可用版本列表后,它会找到符合你项目中所有版本约束的最高版本(有可能其他包对该库的版本要求比你更具体,因此它选择的版本可能并非总是可用的最高版本),然后下载该标签的zip压缩包,并将其解压到vendor目录的正确位置。
如果你希望Composer检出一个分支而不是标签,你需要使用特殊的dev-*前缀(有时是后缀,见下文)将其指向该分支。如果你正在检出一个分支,默认你想要在该分支上工作</b1,Composer会将仓库克隆到你vendor目录中的正确位置。对于标签,它会复制正确的文件,而不会实际克隆仓库。(你可以使用—prefer-source和—prefer-dist修改此行为,参见安装选项</b3。)
在上面的示例中,如果你想检出my-feature分支,你需要在require子句中指定dev-my-feature作为版本约束。这会导致Composer将my-library仓库克隆到我的vendor目录中,并检出my-feature分支。
当分支名称看起来像版本时,我们必须向Composer说明我们要检出的是一个分支,而不是一个标签。在上面的示例中,我们有两个版本分支:v1和v2。要让Composer检出这些分支中的一个,你必须指定如下所示的版本约束:v1.x-dev。.x是Composer要求的一个任意字符串,用于告知它我们说的是
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 值,或者在版本约束中使用“稳定性标记”来实现。更多信息请参见 schema 页面。
编写版本约束
Section titled “编写版本约束”既然您已经了解了Composer如何看待版本,接下来我们来谈谈如何为您的项目依赖项指定版本约束。
精确版本约束
Section titled “精确版本约束”你可以指定一个包的确切版本。这会告诉Composer只安装这个版本。如果其他依赖项需要不同的版本,求解器最终会失败,并中止任何安装或更新过程。
示例:1.0.2
通过使用比较运算符,你可以指定有效版本的范围。有效的运算符有>、>=、<、<=、!=。
您可以定义多个范围。用空格( )或逗号(,)分隔的范围将被视为逻辑与。双竖线(||)将被视为逻辑或。与运算的优先级高于或运算。
**注意:**使用无界范围时要小心,因为你可能会意外安装破坏向后兼容性的版本。为安全起见,考虑改用脱字符运算符。
注意:在旧版本的Composer中,单竖线(
|)是推荐用于替代逻辑或的符号。因此,为了向后兼容,单竖线(|)仍将被视为逻辑或。
示例:
>=1.0>=1.0 <2.0>=1.0 <1.1 || >=1.2
连字符版本范围(-)
Section titled “连字符版本范围(-)”版本的包容性集合。右侧的部分版本包含通配符以完成表达。例如,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
通配符版本范围(.*)
Section titled “通配符版本范围(.*)”你可以使用*通配符指定模式。1.0.*等同于>=1.0 <1.1。
示例:1.0.*
下一个重要版本运算符
Section titled “下一个重要版本运算符”波浪号版本范围(~)
Section titled “波浪号版本范围(~)”~运算符最好通过示例来解释:~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是相同的,因为它不允许主版本号增加,以保持向后兼容性。
脱字符版本范围(^)
Section titled “脱字符版本范围(^)”^运算符的行为非常相似,但它更贴近语义化版本控制,并且始终允许非破坏性更新。例如,^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 |
不过,若要在不将各种稳定性要求作为约束条件强制执行的情况下允许它们存在,你可以使用稳定性标志</b0,例如@<stability>(如@dev),让Composer知道某个特定包可以以不同于默认最低稳定性设置的稳定性级别进行安装。所有可用的稳定性标志都列在模式页面的最低稳定性部分。
"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}测试版本约束
Section titled “测试版本约束”你可以使用semver.madewithlove.com测试版本约束。填写包名称,它会自动填充Composer将添加到你的composer.json文件中的默认版本约束。你可以调整版本约束,该工具会突出显示所有匹配的版本。