本文目录导读:

在 PHP 中,处理语义化版本(Semantic Versioning,简称 SemVer,格式为 主版本.次版本.修订号,1.3)主要有两个核心场景:
- 解析和比较版本号(判断
1.3是否大于1.0)。 - 依赖管理(在
composer.json中声明版本约束)。
下面分别介绍这两种情况。
使用 version_compare() 函数解析和比较版本
PHP 内置的 version_compare() 函数是处理语义版本最直接的工具,它不仅可以比较数字,还能处理预发布标签(如 alpha、beta、RC)。
基本用法:
<?php
$v1 = '2.1.3';
$v2 = '2.1.0';
if (version_compare($v1, $v2, '>')) {
echo "$v1 大于 $v2";
} elseif (version_compare($v1, $v2, '<')) {
echo "$v1 小于 $v2";
} else {
echo "版本相等";
}
// 输出:2.1.3 大于 2.1.0
?>
支持预发布版本:
<?php
// 1.0.0-alpha < 1.0.0-beta < 1.0.0-RC1 < 1.0.0
echo version_compare('1.0.0-alpha', '1.0.0-beta'); // -1 (小于)
echo version_compare('1.0.0-beta', '1.0.0'); // -1 (小于,稳定版 > 任何预发布版)
echo version_compare('1.0.0-RC1', '1.0.0-RC2'); // -1 (小于)
?>
获取当前 PHP 版本并比较:
<?php
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
echo "恭喜,你正在运行 PHP 8.1 或更高版本。";
} else {
echo "请升级到 PHP 8.1 以上。";
}
?>
在 Composer (composer.json) 中定义语义版本约束
这是 PHP 生态中最常见的场景,你需要理解如何精确控制依赖的版本范围。
语义版本规则:
- 精确版本:
"require": {"vendor/package": "1.2.3"}(完全匹配这个版本) - 范围约束(使用
>,<,>=,<=, ):>=1.2.3 <2.0.0
- 波浪号 (锁定主版本和次版本,允许修订号变化):
~1.2等于>=1.2.0 <2.0.0~1.2.3等于>=1.2.3 <1.3.0(常用)
- 脱字符 (锁定主版本,允许次版本和修订号变化):
^1.2.3等于>=1.2.3 <2.0.0^0.3.0等于>=0.3.0 <0.4.0(因为 0.x 版本被认为不稳定)
- *` 通配符**:
2.*等于>=1.2.0 <1.3.0
最佳实践示范(composer.json):
{
"require": {
"monolog/monolog": "^3.0",
"guzzlehttp/guzzle": "~7.2.0",
"php": ">=8.1"
}
}
^3.0:允许 3.0.0 到 3.x.x 的任何更新,但绝不更新到 4.0.0。~7.2.0:允许 7.2.1、7.2.2 等小修复,但不更新到 7.3.0。
自己手动解析完整的 SemVer 格式
如果你需要处理完整的 SemVer 2.0 规范(包含构建元数据 +build),或者需要更精细的控制,可以编写简单函数:
<?php
function parseSemVer(string $version): array
{
// 匹配 SemVer 2.0 格式:主版本.次版本.修订号-预发布+构建
$pattern = '/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-\.]+))?(?:\+([0-9A-Za-z-\.]+))?$/';
if (preg_match($pattern, $version, $matches)) {
return [
'major' => (int)$matches[1],
'minor' => (int)$matches[2],
'patch' => (int)$matches[3],
'pre_release' => $matches[4] ?? '', // "alpha.1" 或 "rc.2"
'build' => $matches[5] ?? '', // "build.123"
];
}
throw new InvalidArgumentException("无效的语义版本: {$version}");
}
// 使用示例
$v = parseSemVer('2.1.3-beta.1+build.456');
print_r($v);
/*
输出:
Array
(
[major] => 2
[minor] => 1
[patch] => 3
[pre_release] => beta.1
[build] => build.456
)
*/
?>
| 场景 | 推荐工具/方法 | 说明 |
|---|---|---|
| 比较版本号 | version_compare() |
内置函数,支持预发布标签,最适合判断更新、安装要求。 |
| 管理依赖 | Composer 符号 | 通过 composer.json 控制包版本范围,是 PHP 现代开发的核心。 |
| 手动解析 | 自定义函数 + 正则 | 当你需要解析完整的 SemVer 2.0 规范(含构建元数据)时使用。 |
核心原则:
如果你的项目是应用,推荐使用 (脱字符)作为默认约束,以获得较小的破坏性更新,如果包本身处于 0.x(开发早期),使用 (波浪号)来限制更严一些,对于生产环境,锁定 composer.lock 文件是必不可少的,它确保所有人使用完全相同的依赖版本。