version_compare

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

version_compare比较两个 "PHP 标准化" 版本号字符串

说明

version_compare(string $version1, string $version2, ?string $operator = null): int|bool

version_compare() 比较两个 "PHP 标准化" 版本号字符串。

该函数首先在版本字符串中用点 . 替换 _-+,并在任何非数字字符前后插入点 .,例如 '4.3.2RC1' 变为 '4.3.2.RC.1'。然后它从左到右比较各部分。如果一个部分包含特殊版本字符串,则按照以下顺序处理:不在此列表中的任何字符串 < dev < alpha = a < beta = b < RC = rc < # < pl = p。这样一来,不仅可以比较像 '4.1' 和 '4.1.2' 这样不同级别的版本,还可以比较任何包含开发状态的 PHP 特定版本。

参数

version1

第一个版本号。

version2

第二个版本号。

operator

一个可选的运算符。可能的运算符有:<lt<=le>gt>=ge===eq!=<>ne

此参数区分大小写,值应为小写。

返回值

默认情况下,version_compare() 如果第一个版本低于第二个版本,则返回 -1;如果它们相等,则返回 0;如果第二个版本低于第一个版本,则返回 1

当使用可选的 operator 参数时,如果关系与运算符指定的相符,则函数将返回 true,否则返回 false

示例

以下示例使用 PHP_VERSION 常量,因为它包含执行代码的 PHP 版本的值。

示例 #1 version_compare() 示例

<?php
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
echo
'我的 PHP 版本至少为 7.0.0,我的版本:' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.3.0') >= 0) {
echo
'我的 PHP 版本至少为 5.3.0,我的版本:' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '>=')) {
echo
'我的 PHP 版本至少为 5.0.0,我的版本:' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '<')) {
echo
'我的 PHP 版本仍然是 PHP 4,我的版本:' . PHP_VERSION . "\n";
}
?>

注释

注意:

PHP_VERSION 常量保存当前 PHP 版本。

注意:

请注意,预发布版本(例如 5.3.0-dev)被认为低于其最终发布版本(例如 5.3.0)。

注意:

alphabeta 这样的特殊版本字符串区分大小写。来自任意来源的、不符合 PHP 标准的版本字符串,可能需要使用 strtolower() 将其转换为小写,然后才能调用 version_compare()

参见

添加注释

用户贡献的注释 9 notes

up
21
eric at themepark dot com
20 years ago
[编辑说明]
在 Matt Mullenweg 的评论后修复了片段

--jm
[/编辑说明]

简而言之,我认为它最好这样使用

<?php
if (version_compare(phpversion(), "4.3.0", ">=")) {
// 您使用的是 4.3.0 或更高版本
} else {
// 您不是
}
?>
up
14
mindplay.dk
12 years ago
这个小程序也许可以帮助您更好地理解版本比较 - 输出显示在顶部的注释中。如果需要更多示例,请调整版本列表...

<?php

# 1 小于 1.0
# 1.0 小于 1.01
# 1.01 等于 1.1
# 1.1 小于 1.10
# 1.10 大于 1.10b
# 1.10b 小于 1.10.0

header('Content-type: text/plain');

$versions = array(
'1',
'1.0',
'1.01',
'1.1',
'1.10',
'1.10b',
'1.10.0',
);

$comps = array(
-
1 => 'lt',
0 => 'eq',
1 => 'gt'
);

foreach (
$versions as $version) {
if (isset(
$last)) {
$comp = version_compare($last, $version);
echo
str_pad($last,8,' ',STR_PAD_LEFT) . " {$comps[$comp]} {$version}\n";
}
$last = $version;
}

?>
up
10
insid0r at yahoo dot com
15 年前
由于此函数认为 1 < 1.0 < 1.0.0,其他人可能会发现此函数有用(它认为 1 == 1.0)

<?php
// 比较两个版本的集合,其中主版本/次版本/等版本由点号隔开。
// 如果两者相等,则返回 0,如果 A > B,则返回 1,如果 B < A,则返回 -1。
function version_compare2($a, $b)
{
$a = explode(".", rtrim($a, ".0")); // 将版本拆分为多个部分,并删除尾部的 .0
$b = explode(".", rtrim($b, ".0")); // 将版本拆分为多个部分,并删除尾部的 .0
foreach ($a as $depth => $aVal)
{
// 遍历 A 的每个部分
if (isset($b[$depth]))
{
// 如果 B 在此深度上与 A 相匹配,则比较值
if ($aVal > $b[$depth]) return 1; // 返回 A > B
else if ($aVal < $b[$depth]) return -1; // 返回 B > A
// 在这一点上,相等的结果是不确定的
}
else
{
// 如果 B 在此深度上与 A 不匹配,则 A 在排序顺序中位于 B 之后
return 1; // 所以返回 A > B
}
}
// 在这一点上,我们知道 A 和 B 扩展到的深度是等价的。
// 循环结束要么是因为 A 比 B 短,要么是因为两者都相等。
return (count($a) < count($b)) ? -1 : 0;
}
?>
up
3
Bob Ray
8 年前
请注意,版本号的前导和尾随空格可能会破坏 version_compare()。

在 PHP 5.6.8 上测试
<?php
echo "\n应该为 0";
echo
"\n '1.0.0-pl' vs. '1.0.0-pl' ---> " . version_compare('1.0.0-pl', '1.0.0-pl');
echo
"\n '1.0.0-pl' vs. ' 1.0.0-pl' ---> " . version_compare('1.0.0-pl', ' 1.0.0-pl');
echo
"\n ' 1.0.0-pl' vs. '1.0.0-pl' ---> " . version_compare(' 1.0.0-pl', '1.0.0-pl');
echo
"\n '1.0.0-pl' vs. '1.0.0-pl ' ---> " . version_compare('1.0.0-pl', '1.0.0-pl ');
echo
"\n '1.0.0-pl ' vs. '1.0.0-pl' ---> " . version_compare('1.0.0-pl ', '1.0.0-pl');

echo
"\n\n应该为 1";
echo
"\n '1.1.1-pl' vs. '1.0.0-pl' ---> " . version_compare('1.1.1-pl', '1.0.0-pl');
echo
"\n ' 1.1.1-pl' vs. '1.0.0-pl' ---> " . version_compare(' 1.1.1-pl', '1.0.0-pl');

echo
"\n\n应该为 -1";
echo
"\n '1.0.0-pl' vs. '1.1.1-pl' ---> " . version_compare('1.0.0-pl', '1.1.1-pl');
echo
"\n '1.0.0-pl' vs. ' 1.1.1-pl' ---> " . version_compare('1.0.0-pl', ' 1.1.1-pl');

/* 输出
应该为 0
'1.0.0-pl' vs. '1.0.0-pl' ---> 0
'1.0.0-pl' vs. ' 1.0.0-pl' ---> 1
' 1.0.0-pl' vs. '1.0.0-pl' ---> -1
'1.0.0-pl' vs. '1.0.0-pl ' ---> 1
'1.0.0-pl ' vs. '1.0.0-pl' ---> -1

应该为 1
'1.1.1-pl' vs. '1.0.0-pl' ---> 1
' 1.1.1-pl' vs. '1.0.0-pl' ---> -1

应该为 -1
'1.0.0-pl' vs. '1.1.1-pl' ---> -1
'1.0.0-pl' vs. ' 1.1.1-pl' ---> 1
*/
up
4
rogier
12 years ago
请注意,如果提供的运算符未列出(例如 ===),则此函数返回 NULL 而不是 false。

在 PHP5.3.0,Win32 上测试
up
4
opendb at iamvegan dot net
17 年前
以下版本比较可能让一些人感到困惑,但值得一提的是:
version_compare('1.0.1', '1.0pl1', '>')

但是,很容易让它正常工作
version_compare('1.0.1', '1.0.0pl1', '>')
up
1
Lcuis
2 年前
如果您需要处理更复杂的版本号,例如 alpha、beta、...,以下是一些可以帮助您的代码

function multiExplode($delimiters,$string){
$pattern = '/['.preg_quote($delimiters).']/';
return(preg_split( $pattern, $string ));
}

function isInteger($input){
return(ctype_digit(strval($input)));
}

function keepIntsStartArray($arr){
$nonIntMappings=[
"alpha"=>1,
"beta"=>2,
"gamma"=>3,
"delta"=>4,
"epsilon"=>5,
"zeta"=>6,
"eta"=>7,
"theta"=>8,
"iota"=>9,
"kappa"=>10,
"lambda"=>11,
"mu"=>12,
"nu"=>13,
"xi"=>14,
"omicron"=>15,
"pi"=>16,
"rho"=>17,
"sigma"=>18,
"tau"=>19,
"upsilon"=>20,
"phi"=>21,
"chi"=>22,
"psi"=>23,
"omega"=>24,
];
$ret=[];
foreach($arr as $i){
if(!isInteger($i)){
if(!array_key_exists($i,$nonIntMappings)){
break;
}
$ret[]=$nonIntMappings[$i];
}
$ret[]=$i;
}
return($ret);
}

function appVersionBigger($v1,$v2,$orEqual=false){
$delimiters=".-+";
$a1=keepIntsStartArray(multiExplode($delimiters,$v1));
$a2=keepIntsStartArray(multiExplode($delimiters,$v2));
$len=count($a1);
if($len>count($a2)){
$len=count($a2);
}
for($i=0;$i<$len;$i++){
$n1=$a1[$i];
$n2=$a2[$i];
if($n1>$n2){
return(true);
}
if($n1<$n2){
return(false);
}
}
if(count($a1)>count($a2)){
return(true);
}
if(count($a1)<count($a2)){
return(false);
}
return($orEqual);
}

// 使用示例

$versions=[
"1.2.3-45"=>"1.2.3-45",
"1.2.3-44"=>"1.2.3-45",
"1.2.3-46"=>"1.2.3-45",
"1.2.3"=>"1.2.3-45",
"1.2.4"=>"1.2.3-45",
"1.2.2"=>"1.2.3-45",
"1.2"=>"1.2.3-45",
"1.3"=>"1.2.3-45",
"1.2.3-ios"=>"1.2.3-and",
"1.2-ios"=>"1.2.3-and",
"2-ios"=>"1.2.3-and",
"1.2.3-alpha"=>"1.2.3-beta",
"1.2.3-beta"=>"1.2.3-alpha",
"1-gamma"=>"1.2.3-beta",
"1-alpha"=>"1.2.3-beta",
];

foreach($versions as $v1=>$v2){
echo("v1: ".$v1."\tv2: ".$v2."\tgt: ".(appVersionBigger($v1,$v2,false)?"true":"false")."\tge: ".(appVersionBigger($v1,$v2,true)?"true":"false")."\n");
}

// 使用 PHP 版本 8.1.8 输出
/*
v1: 1.2.3-45 v2: 1.2.3-45 gt: false ge: true
v1: 1.2.3-44 v2: 1.2.3-45 gt: false ge: false
v1: 1.2.3-46 v2: 1.2.3-45 gt: true ge: true
v1: 1.2.3 v2: 1.2.3-45 gt: false ge: false
v1: 1.2.4 v2: 1.2.3-45 gt: true ge: true
v1: 1.2.2 v2: 1.2.3-45 gt: false ge: false
v1: 1.2 v2: 1.2.3-45 gt: false ge: false
v1: 1.3 v2: 1.2.3-45 gt: true ge: true
v1: 1.2.3-ios v2: 1.2.3-and gt: false ge: true
v1: 1.2-ios v2: 1.2.3-and gt: false ge: false
v1: 2-ios v2: 1.2.3-and gt: true ge: true
v1: 1.2.3-alpha v2: 1.2.3-beta gt: false ge: false
v1: 1.2.3-beta v2: 1.2.3-alpha gt: true ge: true
v1: 1-gamma v2: 1.2.3-beta gt: true ge: true
v1: 1-alpha v2: 1.2.3-beta gt: false ge: false
*/
up
1
sam at wyvern dot non-spammers-remove dot com dot au
20 years ago
实际上,它可以适用于任何程度

<?php
version_compare
('1.2.3.4RC7.7', '1.2.3.4RC7.8')
version_compare('8.2.50.4', '8.2.52.6')
?>

都将返回 -1(即左侧小于右侧)。
up
1
arnoud at procurios dot nl
19 年前
如果您小心谨慎,此函数实际上可以很好地用于比较来自除 PHP 本身以外的程序的版本号。我已使用它来比较 MySQL 版本号。唯一的问题是 version_compare 无法识别 mysql 使用的“gamma”附加项比“alpha”或“beta”更晚,因为后两者经过特殊处理。但是,如果您牢记这一点,您应该不会遇到任何问题。
To Top