PHP 8.2.0 Released!

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', но и специфичные версии, включающие статус разработки.

Список параметров

version1

Номер первой версии.

version2

Номер второй версии.

operator

Необязательный параметр 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 4, моя версия: ' PHP_VERSION "\n";
}
?>

Примечания

Замечание:

Константа PHP_VERSION хранит номер текущей версии PHP.

Замечание:

Заметьте, что дорелизные версии, такие как 5.3.0-dev, считаются меньше, чем финальные (вида 5.3.0).

Замечание:

Специальные слова вроде alpha и beta чувствительны к регистру. Строки версий, не придерживающиеся PHP-стандарта, нужно приводить к нижнему регистру функцией strtolower() до вызова version_compare().

Смотрите также

  • phpversion() - Получает текущую версию PHP
  • php_uname() - Возвращает информацию об операционной системе, на которой запущен PHP
  • function_exists() - Возвращает true, если указанная функция определена

add a note

User Contributed Notes 9 notes

up
20
eric at themepark dot com
18 years ago
[editors note]
snipbit fixed after comment from Matt Mullenweg

--jm
[/editors note]

so in a nutshell... I believe it works best like this:

<?php
if (version_compare(phpversion(), "4.3.0", ">=")) {
 
// you're on 4.3.0 or later
} else {
 
// you're not
}
?>
up
11
mindplay.dk
10 years ago
This little script can perhaps help you understand version comparison a little better - the output is displayed in the comment at the top. Tweak the list of versions if you need more examples...

<?php

#      1 lt 1.0
#    1.0 lt 1.01
#   1.01 eq 1.1
#    1.1 lt 1.10
#   1.10 gt 1.10b
#  1.10b lt 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
13 years ago
Since this function considers 1 < 1.0 < 1.0.0, others might find this function useful (which considers 1 == 1.0):

<?php
//Compare two sets of versions, where major/minor/etc. releases are separated by dots.
//Returns 0 if both are equal, 1 if A > B, and -1 if B < A.
function version_compare2($a, $b)
{
   
$a = explode(".", rtrim($a, ".0")); //Split version into pieces and remove trailing .0
   
$b = explode(".", rtrim($b, ".0")); //Split version into pieces and remove trailing .0
   
foreach ($a as $depth => $aVal)
    {
//Iterate over each piece of A
       
if (isset($b[$depth]))
        {
//If B matches A to this depth, compare the values
           
if ($aVal > $b[$depth]) return 1; //Return A > B
           
else if ($aVal < $b[$depth]) return -1; //Return B > A
            //An equal result is inconclusive at this point
       
}
        else
        {
//If B does not match A to this depth, then A comes after B in sort order
           
return 1; //so return A > B
       
}
    }
   
//At this point, we know that to the depth that A and B extend to, they are equivalent.
    //Either the loop ended because A is shorter than B, or both are equal.
   
return (count($a) < count($b)) ? -1 : 0;
}
?>
up
2
Bob Ray
7 years ago
Note that both leading and trailing spaces on your version numbers can break version_compare().

Tested on PHP 5.6.8:
<?php
echo  "\nShould be 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\nShould be 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\nShould be -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');

   
/* Output
Should be 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

Should be 1
'1.1.1-pl' vs. '1.0.0-pl'  ---> 1
' 1.1.1-pl' vs. '1.0.0-pl' ---> -1

Should be -1
'1.0.0-pl' vs. '1.1.1-pl'  ---> -1
'1.0.0-pl' vs. ' 1.1.1-pl' ---> 1
    */
up
3
rogier
11 years ago
Please note that supplying an operator that is not listed (e.g. ===), this function returns NULL instead of false.

Tested on PHP5.3.0, Win32
up
3
opendb at iamvegan dot net
15 years ago
Something that may trip some folks up, but is useful to mention is that the following version comparison does not work quite as I expected:
    version_compare('1.0.1', '1.0pl1', '>')

However, its quite easy to get working:
    version_compare('1.0.1', '1.0.0pl1', '>')
up
2
arnoud at procurios dot nl
18 years ago
If you're careful, this function actualy works quite nicely for comparing version numbers from programs other than PHP itself. I've used it to compare MySQL version numbers. The only issue is that version_compare doesn't recognize the 'gamma' addition that mysql uses as being later than 'alpha' or 'beta', because the latter two are treated specially. If you keep this in mind though, you should have no problems.
up
0
Lcuis
4 months ago
In case you need to handle more complex version numbers like alpha, beta,..., here is a little something that can help:

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);
}

// usage examples:

$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");
}

// output with php version 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
18 years ago
Actually, it works to any degree:

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

will both give -1 (ie the left is lower than the right).
To Top