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.
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.
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
Salida del ejemplo anterior en 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).
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
}
?>
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!=
.
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.
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'];
}
?>
(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
?>
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';
}
?>
(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
?>