[编辑注]
在 Matt Mullenweg 的评论后修复了代码片段
--jm
[/编辑注]
简而言之……我相信它最好这样工作
<?php
if (version_compare(phpversion(), "4.3.0", ">=")) {
// 您使用的是 4.3.0 或更高版本
} else {
// 您不是
}
?>
(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
version_compare — 比较两个“PHP 标准化”的版本号字符串
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
。
下面的示例使用 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版本仍然是4,我的版本:' . PHP_VERSION . "\n";
}
?>
注意:
PHP_VERSION
常量保存当前PHP版本。
注意:
请注意,预发行版(例如 5.3.0-dev)被认为低于其最终发行版(例如 5.3.0)。
注意:
诸如
alpha
和beta
之类的特殊版本字符串区分大小写。来自任意来源且不符合 PHP 标准的版本字符串可能需要在调用 version_compare() 之前使用 strtolower() 转为小写。
[编辑注]
在 Matt Mullenweg 的评论后修复了代码片段
--jm
[/编辑注]
简而言之……我相信它最好这样工作
<?php
if (version_compare(phpversion(), "4.3.0", ">=")) {
// 您使用的是 4.3.0 或更高版本
} else {
// 您不是
}
?>
这个小脚本或许可以帮助你更好地理解版本比较 - 输出显示在顶部的注释中。如果需要更多示例,请调整版本列表……
<?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;
}
?>
由于此函数认为 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;
}
?>
请注意,版本号上的前导和尾随空格都可能破坏 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
*/
可能让一些人感到困惑,但值得一提的是,以下版本比较的结果并非完全符合我的预期
version_compare('1.0.1', '1.0pl1', '>')
但是,很容易使其正常工作
version_compare('1.0.1', '1.0.0pl1', '>')
如果您需要处理更复杂的版本号,例如 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
*/
实际上,它适用于任何程度
<?php
version_compare('1.2.3.4RC7.7', '1.2.3.4RC7.8')
version_compare('8.2.50.4', '8.2.52.6')
?>
两者都将返回 -1(即左侧小于右侧)。
如果您小心谨慎,此函数实际上非常适合比较来自PHP自身以外程序的版本号。我已经用它来比较MySQL版本号。唯一的问题是,version_compare不识别mysql使用的“gamma”附加版本比“alpha”或“beta”晚,因为后者两者被特殊处理。但是,如果您记住这一点,就不会有任何问题。