z4kn4fein / php-semver
PHP语义化版本库。它实现了完整的语义版本2.0.0规范,并提供了解析、比较和递增语义版本以及验证约束的能力。
Requires
- php: >=8.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10
This package is auto-updated.
Last update: 2024-09-23 13:03:03 UTC
README
PHP语义化版本库。它实现了完整的语义版本2.0.0规范,并提供了解析、比较和递增语义版本以及验证约束的能力。
需求
使用Composer安装
composer require z4kn4fein/php-semver
使用方法
以下选项可用于构建Version
-
使用
Version::create()
逐步构建。Version::create(3, 5, 2, "alpha", "build");
-
使用
Version::parse()
或Version::parseOrNull()
从字符串解析。Version::parse("3.5.2-alpha+build");
构建的Version
对象上可访问以下信息
<?php use z4kn4fein\SemVer\Version; $version = Version::parse("2.5.6-alpha.12+build.34"); echo $version->getMajor(); // 2 echo $version->getMinor(); // 5 echo $version->getPatch(); // 6 echo $version->getPreRelease(); // alpha.12 echo $version->getBuildMeta(); // build.34 echo $version->isPreRelease(); // true echo $version->isStable(); // false echo $version->withoutSuffixes(); // 2.5.6 echo $version; // 2.5.6-alpha.12+build.34
严格与宽松解析
默认情况下,版本解析器将部分版本(如1.0
)和以v
前缀开始的版本视为无效。可以通过将strict
参数设置为false
来关闭此行为。
echo Version::parse("v2.3-alpha"); // exception echo Version::parse("2.1"); // exception echo Version::parse("v3"); // exception echo Version::parse("v2.3-alpha", false); // 2.3.0-alpha echo Version::parse("2.1", false); // 2.1.0 echo Version::parse("v3", false); // 3.0.0
比较
可以使用以下比较方法比较两个Version
对象。
<?php use z4kn4fein\SemVer\Version; // with static methods echo Version::lessThan("2.3.4", "2.4.1"); // true echo Version::lessThanOrEqual("2.4.1", "2.4.1"); // true echo Version::greaterThan("2.3.1-alpha.5", "2.3.1-alpha.3"); // true echo Version::greaterThanOrEqual("3.2.3","3.2.2"); // true echo Version::equal("3.2.3","3.2.3+build.3"); // true echo Version::notEqual("3.2.3","2.2.4"); // true // compare() or compareString() echo Version::compare(Version::parse("2.3.4"), Version::parse("2.4.1")); // -1 echo Version::compare(Version::parse("2.3.4"), Version::parse("2.3.4")); // 0 echo Version::compare(Version::parse("2.3.4"), Version::parse("2.2.0")); // 1 echo Version::compareString("2.3.4", "2.4.1"); // -1 echo Version::compareString("2.3.4", "2.3.4"); // 0 echo Version::compareString("2.3.4", "2.2.0"); // 1 // with instance methods $version = Version::parse("2.5.6-alpha.12+build.34"); echo $version->isLessThan(Version::parse("2.3.1")); // false echo $version->isLessThanOrEqual(Version::parse("2.5.6-alpha.15")); // true echo $version->isGreaterThan(Version::parse("2.5.6")); // false echo $version->isLessThanOrEqual(Version::parse("2.5.6-alpha.12")); // true echo $version->isEqual(Version::parse("2.5.6-alpha.12+build.56")); // true echo $version->isNotEqual(Version::parse("2.2.4")); // true
排序
Version::sort()
和Version::sortString()
可用于排序版本数组。
<?php use z4kn4fein\SemVer\Version; $versions = array_map(function(string $version) { return Version::parse($version); }, [ "1.0.1", "1.0.1-alpha", "1.0.1-alpha.beta", "1.0.1-alpha.3", "1.0.1-alpha.2", "1.1.0", "1.1.0+build", ]); $sorted = Version::sort($versions); // The result: // "1.0.1-alpha" // "1.0.1-alpha.2" // "1.0.1-alpha.3" // "1.0.1-alpha.beta" // "1.0.1" // "1.1.0" // "1.1.0+build"
如果您想按反向顺序排序,则可以使用Version::rsort()
或Version::rsortString()
。
<?php use z4kn4fein\SemVer\Version; $versions = array_map(function(string $version) { return Version::parse($version); }, [ "1.0.1", "1.0.1-alpha", "1.0.1-alpha.beta", "1.0.1-alpha.3", "1.0.1-alpha.2", "1.1.0", "1.1.0+build", ]); $sorted = Version::rsort($versions); // The result: // "1.1.0" // "1.1.0+build" // "1.0.1" // "1.0.1-alpha.beta" // "1.0.1-alpha.3" // "1.0.1-alpha.2" // "1.0.1-alpha"
Version::compare()
和Version::compareString()
方法也可以用作usort()
的回调来排序版本数组。
<?php use z4kn4fein\SemVer\Version; $versions = array_map(function(string $version) { return Version::parse($version); }, [ "1.0.1", "1.0.1-alpha", "1.0.1-alpha.beta", "1.0.1-alpha.3", "1.0.1-alpha.2", "1.1.0", "1.1.0+build", ]); usort($versions, ["z4kn4fein\SemVer\Version", "compare"]); // The result: // "1.0.1-alpha" // "1.0.1-alpha.2" // "1.0.1-alpha.3" // "1.0.1-alpha.beta" // "1.0.1" // "1.1.0" // "1.1.0+build"
约束
使用约束,可以验证版本是否满足一组规则。约束可以描述为一组条件,这些条件通过逻辑OR
和AND
运算符组合。
条件
条件通常由比较运算符和版本组成,如>=1.2.0
。条件>=1.2.0
将由任何大于或等于1.2.0
的版本满足。
支持的比较运算符
=
相等(相当于无运算符:1.2.0
意味着=1.2.0
)!=
不相等<
小于<=
小于等于>
大于>=
大于等于
可以使用空格将条件连接起来,表示它们之间的逻辑AND
运算符。OR
运算符可以用||
或|
在条件集中表示。
例如,约束>=1.2.0 <3.0.0 || >4.0.0
表示:仅允许那些大于或等于1.2.0
且小于3.0.0
或大于4.0.0
的版本。
我们可以注意到前一个约束的第一个部分(>=1.2.0 <3.0.0
)是一个简单的语义版本范围。还有更多表达版本范围的方式;下一节将介绍所有可用的选项。
范围条件
有一些特定的范围指示符,它们是更广泛的范围表达式的简写。
-
X-Range:可以使用
x
、X
和*
字符作为版本数字部分的通配符。1.2.x
转换为>=1.2.0 <1.3.0-0
1.x
转换为>=1.0.0 <2.0.0-0
*
转换为>=0.0.0
在部分版本表达式中,缺失的数字被视为通配符。
1.2
表示1.2.x
,最终转换为>=1.2.0 <1.3.0-0
1
表示1.x
或1.x.x
,最终转换为>=1.0.0 <2.0.0-0
-
连字符范围:描述一个包含的版本范围。通配符将被评估并在最终范围内考虑。
1.0.0 - 1.2.0
转换为>=1.0.0 <=1.2.0
1.1 - 1.4.0
表示>=(>=1.1.0 <1.2.0-0) <=1.4.0
,最终转换为>=1.1.0 <=1.4.0
1.1.0 - 2
表示>=1.1.0 <=(>=2.0.0 <3.0.0-0)
,最终转换为>=1.1.0 <3.0.0-0
-
波浪号范围 (
~
):当指定次要版本时,描述补丁级别范围;未指定时,描述次要级别范围。~1.0.1
转换为>=1.0.1 <1.1.0-0
~1.0
转换为>=1.0.0 <1.1.0-0
~1
转换为>=1.0.0 <2.0.0-0
~1.0.0-alpha.1
转换为>=1.0.1-alpha.1 <1.1.0-0
-
插入符号范围 (
^
):描述与版本最左非零部分的有关范围。^1.1.2
转换为>=1.1.2 <2.0.0-0
^0.1.2
转换为>=0.1.2 <0.2.0-0
^0.0.2
转换为>=0.0.2 <0.0.3-0
^1.2
转换为>=1.2.0 <2.0.0-0
^1
转换为>=1.0.0 <2.0.0-0
^0.1.2-alpha.1
转换为>=0.1.2-alpha.1 <0.2.0-0
验证
让我们看看我们如何确定一个版本是否满足约束。
<?php use z4kn4fein\SemVer\Version; use z4kn4fein\SemVer\Constraints\Constraint; $constraint = Constraint::parse(">=1.2.0"); $version = Version::parse("1.2.1"); echo $version->isSatisfying($constraint); // true echo $constraint->isSatisfiedBy($version); // true // Or using the static satisfies() method with strings: echo Version::satisfies("1.2.1", ">=1.2.0"); // true
增加
Version
对象可以使用 getNext{Major|Minor|Patch|PreRelease}Version
方法生成自己的增加版本。这些方法可以用来确定下一个版本,按相应部分顺序增加。Version
对象是 不可变的,所以每个增加函数都会创建一个新的 Version
。
此示例显示了在稳定版本上的增加是如何工作的
<?php use z4kn4fein\SemVer\Version; use z4kn4fein\SemVer\Inc; $stableVersion = Version::create(1, 0, 0); echo $stableVersion->getNextMajorVersion(); // 2.0.0 echo $stableVersion->getNextMinorVersion(); // 1.1.0 echo $stableVersion->getNextPatchVersion(); // 1.0.1 echo $stableVersion->getNextPreReleaseVersion(); // 1.0.1-0 // or with the inc() method: echo $stableVersion->inc(Inc::MAJOR); // 2.0.0 echo $stableVersion->inc(Inc::MINOR); // 1.1.0 echo $stableVersion->inc(Inc::PATCH); // 1.0.1 echo $stableVersion->inc(Inc::PRE_RELEASE); // 1.0.1-0
在不稳定版本的情况下
<?php use z4kn4fein\SemVer\Version; use z4kn4fein\SemVer\Inc; $unstableVersion = Version::parce("1.0.0-alpha.2+build.1"); echo $unstableVersion->getNextMajorVersion(); // 2.0.0 echo $unstableVersion->getNextMinorVersion(); // 1.1.0 echo $unstableVersion->getNextPatchVersion(); // 1.0.0 echo $unstableVersion->getNextPreReleaseVersion(); // 1.0.0-alpha.3 // or with the inc() method: echo $unstableVersion->inc(Inc::MAJOR); // 2.0.0 echo $unstableVersion->inc(Inc::MINOR); // 1.1.0 echo $unstableVersion->inc(Inc::PATCH); // 1.0.0 echo $unstableVersion->inc(Inc::PRE_RELEASE); // 1.0.0-alpha.3
每个增加函数都提供了在增加版本上设置预发布标识符的选项。
<?php use z4kn4fein\SemVer\Version; use z4kn4fein\SemVer\Inc; $version = Version::parce("1.0.0-alpha.1"); echo $version->getNextMajorVersion("beta"); // 2.0.0-beta echo $version->getNextMinorVersion(""); // 1.1.0-0 echo $version->getNextPatchVersion("alpha"); // 1.0.1-alpha echo $version->getNextPreReleaseVersion("alpha"); // 1.0.0-alpha.2 // or with the inc() method: echo $version->inc(Inc::MAJOR, "beta"); // 2.0.0-beta echo $version->inc(Inc::MINOR, ""); // 1.1.0-0 echo $version->inc(Inc::PATCH, "alpha"); // 1.0.1-alpha echo $version->inc(Inc::PRE_RELEASE, "alpha"); // 1.0.0-alpha.2
复制
可以使用 copy()
方法创建特定版本的副本。它允许使用可选参数更改复制的版本属性。
$version = Version::parse("1.0.0-alpha.2+build.1"); echo $version->copy(); // 1.0.0-alpha.2+build.1 echo $version->copy(3); // 3.0.0-alpha.2+build.1 echo $version->copy(null, 4); // 1.4.0-alpha.2+build.1 echo $version->copy(null, null, 5); // 1.0.5-alpha.2+build.1 echo $version->copy(null, null, null, "alpha.4"); // 1.0.0-alpha.4+build.1 echo $version->copy(null, null, null, null, "build.3"); // 1.0.0-alpha.2+build.3 echo $version->copy(3, 4, 5); // 3.4.5-alpha.2+build.1
注意
如果不设置任何可选参数,则 copy()
方法将生成原始版本的精确副本。
无效版本处理
当版本或约束解析因格式无效而失败时,库抛出特定的 SemverException
。
注意
可以使用 Version::parseOrNull()
和 Constraint::parseOrNull()
方法进行异常无转换,因为当解析失败时,它们返回 null
。