version_compare

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

version_compareComparar dos strings de versión en el formato de versiones de PHP

Descripción

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

version_compare() compara dos versiones de PHP estandarizadas.

version_compare() reemplaza inicialmente _, - y + por un punto (.) en los strings de versión y también inserta puntos antes y después de cualquier carácter no numérico para que, por ejemplo, '4.3.5RC1' se convierta en '4.3.5.RC.1'. Luego, compara los fragmentos de izquierda a derecha. Si una parte contiene caracteres alfabéticos, estos son gestionados en el siguiente orden: any string not found in this list < dev < alpha = a < beta = b < RC = rc < # < pl = p. De esta manera, es posible comparar no solo versiones de diferentes niveles, como '4.1' y '4.1.2', sino también versiones de desarrollo de PHP, en cualquier etapa.

Parámetros

version1

Primer número de versión.

version2

Segundo número de versión.

operator

Un operador opcional. Los operadores posibles son: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectivamente.

Este parámetro es sensible a mayúsculas/minúsculas, por lo que los valores deben estar en minúsculas.

Valores devueltos

Por omisión, version_compare() devuelve -1 si la primera versión es inferior a la segunda, 0 si son iguales, y 1 si la segunda es inferior a la primera.

Cuando se utiliza el parámetro opcional operator, la función devuelve true si la relación es la especificada por el operador, false en caso contrario.

Ejemplos

Los ejemplos siguientes utilizan la constante PHP_VERSION, sabiendo que contiene el valor de la versión de PHP utilizada para ejecutar el código.

Ejemplo #1 Ejemplo con version_compare()

<?php
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
echo
'Tengo al menos la versión 7.0.0 de PHP; mi versión: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.3.0') >= 0) {
echo
'Tengo al menos la versión 5.3.0 de PHP; mi versión: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '>=')) {
echo
'Tengo al menos la versión 5.0.0 de PHP; mi versión: ' . PHP_VERSION . "\n";
}

if (
version_compare(PHP_VERSION, '5.0.0', '<')) {
echo
'Aún utilizo PHP 4; mi versión: ' . PHP_VERSION . "\n";
}
?>

Notas

Nota:

La constante PHP_VERSION contiene la versión actual de PHP.

Nota:

Tenga en cuenta que las versiones intermedias, como 5.3.0-dev, son consideradas inferiores a sus versiones finales (como 5.3.0).

Nota:

Los strings especiales de versión como alpha y beta son sensibles a mayúsculas/minúsculas. Los strings de versión provenientes de fuentes arbitrarias que no siguen el estándar de PHP deben ser convertidos a minúsculas utilizando la función strtolower() antes de llamar a la función version_compare().

Ver también

add a note

User Contributed Notes 9 notes

up
21
eric at themepark dot com
21 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
14
mindplay.dk
12 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
16 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
9 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
13 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
18 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
2 years 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
21 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
20 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