CakeFest 2024: The Official CakePHP Conference

version_compare

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

version_compareVergleicht zwei Versionsnummer-Zeichenketten im PHP-Versionsformat

Beschreibung

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

version_compare() vergleicht zwei dem PHP-Versionsformat angeglichene Versionsnummer-Zeichenketten.

Zuerst ersetzt die Funktion _, - und + durch einen Punkt . in den Versionsangaben und setzt vor und nach jeder Kette aus nicht-numerischen Zeichen Punkte ein, sodass beispielsweise '4.3.2RC1' zu '4.3.2.RC.1' wird. Anschließend werden von links nach rechts die Teile verglichen. Wenn ein Teil spezielle Zeichen enthält, werden diese nach der folgenden Reihenfolge behandelt: jede Zeichenkette, die nicht in dieser Liste vorkommt < dev < alpha = a < beta = b < RC = rc < # < pl = p. Auf diese Weise können nicht nur Versionen verschiedener Tiefe wie '4.1' und '4.1.2', sondern auch alle anderen Versionen verglichen werden, die sich auf bestimmte Entwicklungsstadien von PHP beziehen.

Parameter-Liste

version1

Die erste Versionsnummer.

version2

Die zweite Versionsnummer.

operator

Ein optionaler Parameter; mögliche Operatoren sind: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <> und ne.

Dieser Parameter berücksicht die Groß- und Kleinschreibung. Die Werte sollten alle kleingeschrieben werden.

Rückgabewerte

Standardmäßig gibt version_compare() -1 zurück, wenn die erste Version kleiner ist als die zweite, 0, wenn die Versionen gleich sind und 1, wenn die zweite Version kleiner ist.

Wenn der optionale Parameter operator übergeben wurde, gibt die Funktion true oder false zurück, je nach dem, ob das mit dem Operator definierte Verhältnis der Wahrheit entspricht oder nicht.

Beispiele

Das untenstehende Beispiel verwendet die Konstante PHP_VERSION, die die Version des aktuell ausführenden PHP-Interpreters enthält.

Beispiel #1 version_compare()-Beispiele

<?php
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
echo
'Ich bin mindestens PHP 7.0.0, meine Version: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.3.0') >= 0) {
echo
'Ich bin mindestens PHP 5.3.0, meine Version: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '>=')) {
echo
'Ich bin mindestens PHP 5.0.0, meine Version: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '<')) {
echo
'Ich bin noch PHP 4, meine Version: ' . PHP_VERSION . "\n";
}
?>

Anmerkungen

Hinweis:

Die Konstante PHP_VERSION enthält die aktuelle PHP-Version

Hinweis:

Vorveröffentlichte Versionen wie 5.3.0-dev werden als kleiner erkannt als ihre finalen Veröffentlichungen (wie 5.3.0).

Hinweis:

Bei besonderen Versionszeichenketten wie alpha und beta wird zwischen Groß-/Kleinschreibung unterschieden. Versionszeichenketten aus beliebigen Quellen, die nicht den PHP-Standard einhalten, müssen bei Bedarf mit strtolower() in Kleinschreibung umgewandelt werden, bevor version_compare() aufgerufen wird.

Siehe auch

  • phpversion() - Liefert die aktuelle PHP-Version
  • php_uname() - Returns information about the operating system PHP is running on
  • function_exists() - Falls die angegebene Funktion definiert ist, wird true zurück gegeben

add a note

User Contributed Notes 10 notes

up
21
eric at themepark dot com
19 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
13
mindplay.dk
11 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
15 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
3
Bob Ray
8 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
12 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
4
opendb at iamvegan dot net
16 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
1
Lcuis
1 year 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
hello at chrisreynolds dot io
14 days ago
Worth noting that `-1` is not equivalent to `false`. Which is to say that:

$current_version = "1.0.0";
$compared_version = "1.2.0";

// if ( 1 )
if (version_compare($current_version, $compared_version) {
echo "A newer version is available"; // this is true
}

but also

$current_version = "1.3.0";
$compared_version = "1.2.0";

// if ( -1 )
if (version_compare($current_version, $compared_version) {
echo "You are on the most recent version."; // this is also true
}

In other words, don't rely on the default behavior (the first value is greater than the second value) if what you want is a boolean.
up
1
sam at wyvern dot non-spammers-remove dot com dot au
19 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).
up
1
arnoud at procurios dot nl
19 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.
To Top