Operadores de comparación

Los operadores de comparación, como su nombre indica, te permiten comparar dos valores. También puede que te interese ver las tablas de comparación de tipos, ya que muestran ejemplos de varias comparaciones relacionadas con tipos.

Operadores de comparación
Ejemplo Nombre Resultado
$a == $b Igual true si $a es igual a $b después de la conversión de tipos.
$a === $b Identico true si $a es igual a $b, y son del mismo tipo.
$a != $b No igual true si $a no es igual a $b después de la conversión de tipos.
$a <> $b No igual true si $a no es igual a $b después de la conversión de tipos.
$a !== $b No identico true si $a no es igual a $b, o no son del mismo tipo.
$a < $b Menor que true si $a es estricatamente menor que $b.
$a > $b Mayor que true si $a es estrictamente mayor que $b.
$a <= $b Menor o igual a true si $a es menor o igual a $b.
$a >= $b Mayor o igual a true si $a es mayor o igual a $b.
$a <=> $b Operador combinado (operador de nave espacial) Un int menor que, igual a, o mayor que cero cuando $a es menor que, igual a, o mayor que $b, respectivamente.

Si ambos operandos son cadenas numéricas, o uno de los operandos es un número y el otro es una cadena numérica, entonces la comparación se realiza numéricamente. Estos reglas también se aplican a la sentencia switch. El tipo de conversión no se realiza cuando la comparación es === o !== ya que esto implica comparar tanto el tipo como el valor.

Advertencia

Antes de PHP 8.0.0, si una string es comparada con un número o una cadena numérica entonces la string era convertida a un número antes de realizar la comparación. Esto puede llevar a resultados sorprendentes como se puede ver en el siguiente ejemplo:

<?php
var_dump
(0 == "a");
var_dump("1" == "01");
var_dump("10" == "1e1");
var_dump(100 == "1e2");

switch (
"a") {
case
0:
echo
"0";
break;
case
"a":
echo
"a";
break;
}
?>

Salida del ejemplo anterior en PHP 7:

bool(true)
bool(true)
bool(true)
bool(true)
0

Output of the above example in PHP 8:

bool(false)
bool(true)
bool(true)
bool(true)
a

<?php
// Enteros
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Números de punto flotante
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Cadenas
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1

// Arrays
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

// Objetos
$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo
$a <=> $b; // 0

$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo
$a <=> $b; // -1

$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo
$a <=> $b; // 1

// no solo se comparan los valores; las claves deben coincidir
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo
$a <=> $b; // 1

?>

Para varios tipos, la comparación se realiza de acuerdo a la siguiente tabla (en orden).

Comparación con Varios Tipos
Tipo de Operando 1 Tipo de Operando 2 Resultado
null o string string Convertir null a "", comparación numérica o léxica
bool o null cualquier cosa Comvertir ambos operandos a bool, false < true
object object Las clases incorporadas pueden definir su propia comparación, clases diferentes son incomparables, para clases iguales ver Comparación de Objetos
string, recurso, int o float string, recurso, int o float Convertir strings y recursos a números, matemática usual
array array Array con más miembros es mayor, si key de operando 1 no se encuentra en el operando 2 entonces los arrays son incomparables, en caso contrario - comparar valor por valor (ver siguiente ejemplo)
object cualquier cosa El object es siempre mayor
array cualquier cosa El array es siempre mayor

Ejemplo #1 Comparacion Booleano/null

<?php
// Bool y null son comparados siempre como bool
var_dump(1 == TRUE); // TRUE - igual que (bool) 1 == TRUE
var_dump(0 == FALSE); // TRUE - igual que (bool) 0 == FALSE
var_dump(100 < TRUE); // FALSE - igual que (bool) 100 < TRUE
var_dump(-10 < FALSE);// FALSE - igual que (bool) -10 < FALSE
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool) NULL < (bool) -100 es FALSE < TRUE
?>

Ejemplo #2 Transcripción de comparación de arrays estándar

<?php
// Arrays con comparadas como esto con operadores de comparación estándar así como el operador de nave espacial.
function standard_array_compare($op1, $op2)
{
if (
count($op1) < count($op2)) {
return -
1; // $op1 < $op2
} elseif (count($op1) > count($op2)) {
return
1; // $op1 > $op2
}
foreach (
$op1 as $key => $val) {
if (!
array_key_exists($key, $op2)) {
return
1;
} elseif (
$val < $op2[$key]) {
return -
1;
} elseif (
$val > $op2[$key]) {
return
1;
}
}
return
0; // $op1 == $op2
}
?>

Advertencia

Comparación de números de punto flotante

Devido a la forma en que los floats son representados internamente, no deberías comparar dos floats para igualdad.

Vease la documentación para float para más información.

Nota: Tenga en cuenta que la conversión de tipos de PHP no siempre es obvia al comparar valores de diferentes tipos, particularmente comparando ints con bools o ints con strings. Por lo tanto, generalmente es recomendable usar comparaciones === y !== en la mayoría de los casos en lugar de == y !=.

Valores Incomparables

Mientras las comparaciones de identidad (=== y !==) pueden ser aplicadas a valores arbitrarios, los otros operadores de comparación solo deberían ser aplicados a valores comparables. El resultado de comparar valores incomparables es indefinido, y no debería depender de ello.

Operador ternario

Otro operador condicional es el operador "?:" (o ternario).

Ejemplo #3 Asignando un valor por defecto

<?php
// Ejemplo de uso: Operador ternario
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];

// Lo anterior es idéntico a esta sentencia if/else
if (empty($_POST['action'])) {
$action = 'default';
} else {
$action = $_POST['action'];
}
?>
La expresión (expr1) ? (expr2) : (expr3) se evalúa expr2 si expr1 es evaluado como true, y expr3 si expr1 es evaluado como false.

Es posible omitir la parte media del operador ternario. La expresión expr1 ?: expr3 devuelve el resultado de expr1 si expr1 es evaluado como true, y expr3 en caso contrario. expr1 solo es evaluado una vez en este caso.

Nota: Por favor tenga en cuenta que el operador ternario es una expresión, y como tal no es evaluado como una variable, pero sí al resultado de una expresión. Es importante saber esto si se quiere devolver una variable por referencia. La sentencia return $var == 42 ? $a : $b; en una devolución por referencia por lo tanto, no funcionará y se emitirá una advertencia.

Nota:

Es recomendable evitar "apilar" expresiones ternarias. El comportamiento de PHP cuando se usan más de un operador ternario sin paréntesis en una sola expresión no es obvio en comparación con otros lenguajes de programación. De hecho, antes de PHP 8.0.0, las expresiones ternarias se evaluaban de izquierda a derecha, en lugar de derecha a izquierda como la mayoría de los otros lenguajes de programación. Depender de la asociatividad de izquierda está obsoleto a partir de PHP 7.4.0. A partir de PHP 8.0.0, el operador ternario no es asociativo.

Ejemplo #4 Comportamiento no-obvio del operador Ternario

<?php
// En primer momento, lo siguiente parece devolver 'true'
echo (true ? 'true' : false ? 't' : 'f');

// Sin embargo, la salida real de lo anterior es 't' antes de PHP 8.0.0
// esto es porque las expresiones ternarias son asociativas a la izquierda

// La siguiente es una versión más obvia del mismo código que el anterior
echo ((true ? 'true' : false) ? 't' : 'f');

// Aquí, uno puede ver que la primera expresión se evalúa a 'true', que
// a su vez se evalúa a (bool) true, devolviendo así la rama verdadera de la
// segunda expresión ternaria.
?>

Nota:

Encadenando expresiones ternarias cortas (?:), sin embargo, es estable y se comporta razonablemente. Se evaluará al primer argumento que se evalúe como un valor no falso. Tenga en cuenta que los valores indefinidos seguirán generando una advertencia.

Ejemplo #5 Encadenado ternarios cortos

<?php
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
?>

Operador de Coalescencia de Nulos

Otro operador condicional útil es el operador "??" (o de coalescencia de nulos). Another useful shorthand operator is the "??" (or null coalescing) operator.

Ejemplo #6 Asignando un valor por defecto

<?php
// Ejemplo de uso: Operador de Coalescencia de Nulos
$action = $_POST['action'] ?? 'default';

// Lo anterior es idéntico a esta sentencia if/else
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else {
$action = 'default';
}
?>
La expresión (expr1) ?? (expr2) se evalúa a expr2 si expr1 es null, y expr1 en caso contrario.

En particular, este operador no emite un aviso o advertencia si el valor del lado izquierdo no existe, al igual que isset(). Esto es especialmente útil en claves de arrays.

Nota: Por favor tenga en cuenta que el operador de coalescencia de nulos es una expresión, y como tal no es evaluado como una variable, pero sí al resultado de una expresión. Es importante saber esto si se quiere devolver una variable por referencia. La sentencia return $foo ?? $bar; en una devolución por referencia por lo tanto, no funcionará y se emitirá una advertencia.

Nota:

El operador de coalescencia de nulos tiene una baja precedencia. Esto significa que si se mezcla con otros operadores (como la concatenación de cadenas o los operadores aritméticos) probablemente se requerirán paréntesis.

<?php
// Emitirá una advertencia de que $name es indefinido.
print 'Mr. ' . $name ?? 'Anonymous';

// Imprime "Mr. Anonymous"
print 'Mr. ' . ($name ?? 'Anonymous');
?>

Nota:

Tenga en cuenta que el operador de coalescencia de nulos permite anidamiento simple:

Ejemplo #7 Anidamiento del operador de coalescencia de nulos

<?php

$foo
= null;
$bar = null;
$baz = 1;
$qux = 2;

echo
$foo ?? $bar ?? $baz ?? $qux; // Imprime 1

?>

add a note

User Contributed Notes 14 notes

up
170
crazy888s at hotmail dot com
15 years ago
I couldn't find much info on stacking the new ternary operator, so I ran some tests:

<?php
echo 0 ?: 1 ?: 2 ?: 3; //1
echo 1 ?: 0 ?: 3 ?: 2; //1
echo 2 ?: 1 ?: 0 ?: 3; //2
echo 3 ?: 2 ?: 1 ?: 0; //3

echo 0 ?: 1 ?: 2 ?: 3; //1
echo 0 ?: 0 ?: 2 ?: 3; //2
echo 0 ?: 0 ?: 0 ?: 3; //3
?>

It works just as expected, returning the first non-false value within a group of expressions.
up
5
gfilippakis at sleed dot gr
1 year ago
Please note that using the null coalescing operator to check properties on a class that has the __get magic method (without an __isset magic method) invokes the magic method.

For example:

<?php

class A
{
public function
__get($property)
{
echo
'Called __get for ' . $property . PHP_EOL;
}
}

$a = new A();

echo
'Trying null coalescing operator' . PHP_EOL;
$b = $a->test ?? 5;

echo
'Trying isset()' . PHP_EOL;
if (isset(
$a->test)) {
$b = $a->test;
} else {
$b = 5;
}

?>
up
21
adam at caucho dot com
18 years ago
Note: according to the spec, PHP's comparison operators are not transitive. For example, the following are all true in PHP5:

"11" < "a" < 2 < "11"

As a result, the outcome of sorting an array depends on the order the elements appear in the pre-sort array. The following code will dump out two arrays with *different* orderings:

<?php
$a
= array(2, "a", "11", 2);
$b = array(2, "11", "a", 2);
sort($a);
var_dump($a);
sort($b);
var_dump($b);
?>

This is not a bug report -- given the spec on this documentation page, what PHP does is "correct". But that may not be what was intended...
up
9
Tahazzot
3 years ago
Very careful when reading PHP documentation, Here's a lot of miss information.

According to documentation, They say's (int) 0 == (string) "a" is true. But it is not in PHP 8.

var_dump(0 == "a"); // 0 == 0 -> true

Now In PHP 8 it's False.
up
5
Sumon Mahmud
5 years ago
Extending from here: https://www.php.net/manual/en/language.operators.comparison.php#121907

$a = ['a' => 1, 'b' => 2, 'c' => 3, 'e' => 4];
$b = ['a' => 1, 'b' => 2, 'd' => 3, 'e' => 4];

echo $a > $b; // 0
echo $b > $a; // 0
echo $a <$b; // 0
echo $b < $a; // 0

If using spaceship operator then it is returning true like :

echo $a <=> $b; //1
echo $b <=> $a; //1
echo $a <=> $b; //1
echo $b <=> $a; //1
up
16
rshawiii at yahoo dot com
19 years ago
You can't just compare two arrays with the === operator
like you would think to find out if they are equal or not. This is more complicated when you have multi-dimensional arrays. Here is a recursive comparison function.

<?php
/**
* Compares two arrays to see if they contain the same values. Returns TRUE or FALSE.
* usefull for determining if a record or block of data was modified (perhaps by user input)
* prior to setting a "date_last_updated" or skipping updating the db in the case of no change.
*
* @param array $a1
* @param array $a2
* @return boolean
*/
function array_compare_recursive($a1, $a2)
{
if (!(
is_array($a1) and (is_array($a2)))) { return FALSE;}

if (!
count($a1) == count($a2))
{
return
FALSE; // arrays don't have same number of entries
}

foreach (
$a1 as $key => $val)
{
if (!
array_key_exists($key, $a2))
{return
FALSE; // uncomparable array keys don't match
}
elseif (
is_array($val) and is_array($a2[$key])) // if both entries are arrays then compare recursive
{if (!array_compare_recursive($val,$a2[$key])) return FALSE;
}
elseif (!(
$val === $a2[$key])) // compare entries must be of same type.
{return FALSE;
}
}
return
TRUE; // $a1 === $a2
}
?>
up
13
bishop
18 years ago
When you want to know if two arrays contain the same values, regardless of the values' order, you cannot use "==" or "===". In other words:

<?php
(array(1,2) == array(2,1)) === false;
?>

To answer that question, use:

<?php
function array_equal($a, $b) {
return (
is_array($a) && is_array($b) && array_diff($a, $b) === array_diff($b, $a));
}
?>

A related, but more strict problem, is if you need to ensure that two arrays contain the same key=>value pairs, regardless of the order of the pairs. In that case, use:

<?php
function array_identical($a, $b) {
return (
is_array($a) && is_array($b) && array_diff_assoc($a, $b) === array_diff_assoc($b, $a));
}
?>

Example:
<?php
$a
= array (2, 1);
$b = array (1, 2);
// true === array_equal($a, $b);
// false === array_identical($a, $b);

$a = array ('a' => 2, 'b' => 1);
$b = array ('b' => 1, 'a' => 2);
// true === array_identical($a, $b)
// true === array_equal($a, $b)
?>

(See also the solution "rshawiii at yahoo dot com" posted)
up
6
admin at zeros dot co dot id
2 years ago
Please be careful when you try to compare strings that have a plus sign `+` at the beginning (such as phone number, etc). When you use the Equal operator `==` PHP will ignore the plus sign. Use Identical operator `===` instead

Example:

$str1 = "62";
$str2 = "+62";

var_dump($str1 == $str2); // bool(true)
var_dump($str1 === $str2); // bool(false)
up
4
niall at maranelda dot org
7 years ago
Care must be taken when using the spaceship operator with arrays that do not have the same keys:

- Contrary to the notes above ("Example #2 Transcription of standard array comparison"), it does *not* return null if the left-hand array contains a key that the right-hand array does not.
- Because of this, the result depends on the order you do the comparison in.

For example:

<?php
$a
= ['a' => 1, 'b' => 2, 'c' => 3, 'e' => 4];
$b = ['a' => 1, 'b' => 2, 'd' => 3, 'e' => 4];

var_dump($a <=> $b); // int(1) : $a > $b because $a has the 'c' key and $b doesn't.

var_dump($b <=> $a); // int(1) : $b > $a because $b has the 'd' key and $a doesn't.
?>
up
4
Ryan Mott
5 years ago
Searching for "double question mark" operator should find this page (and hopefully after this comment the crawlers will agree)
up
1
Hayley Watson
1 year ago
Between the "shortcut ternary" (aka "elvis") and "spaceship" operators, you can write some quite compact comparison functions for usort and its ilk.

If you want to sort an array of associative arrays by several different keys you can chain them in the same way that you can list column names in an SQL ORDER BY clause.

<?php
usort
($array, fn($a, $b) => $a['a'] <=> $b['a']
?:
$b['b'] <=> $a['b']
?:
$a['c'] <=> $b['c']);
?>
Will sort the array by column 'a', then by column 'b' descending, then by column 'c'; or in SQL-speak 'ORDER BY a, b DESC, c".
up
6
Cuong Huy To
13 years ago
In the table "Comparison with Various Types", please move the last line about "Object" to be above the line about "Array", since Object is considered to be greater than Array (tested on 5.3.3)

(Please remove my "Anonymous" post of the same content before. You could check IP to see that I forgot to type my name)
up
1
Marcin Kuzawiski
9 years ago
A < B and still B < A...

$A = [1 => 1, 2 => 0, 3 => 1];
$B = [1 => 1, 3 => 0, 2 => 1];

var_dump($A < $B); // TRUE
var_dump($B < $A); // TRUE

var_dump($A > $B); // TRUE
var_dump($B > $A); // TRUE

Next - C and D are comparable, but neither C < D nor D < C (and still C != D)...

$C = [1 => 1, 2 => 1, 3 => 0];
$D = [1 => 1, 3 => 1, 2 => 0];

var_dump($C < $D); // FALSE
var_dump($D < $C); // FALSE

var_dump($C > $D); // FALSE
var_dump($D > $C); // FALSE

var_dump($D == $C); // FALSE
up
-1
billynoah at gmail dot com
30 days ago
It's worth noting that there can be a difference in the logical operation of shorthand ternary (expr1 ?: expr2) vs the full version (expr1 ? expr1 : expr2). The shorthand style may also offer a slight performance enhancement because the initial expression will only be evaluated once.

Example:
<?php
// my_func() will be called twice here
// additionally, my_func() may not return the same value both times!
$var = my_func() ? my_func() : false;

// my_func() will only be called once here
$var = my_func() ?: false;
To Top