Las operaciones lógicas son expresiones matemáticas cuyo resultado es un valor booleano (verdadero o falso, en PHP, true o false). Estas expresiones se utilizan principalmente en las estructuras de control.
Las comparaciones permiten comparar variables o expresiones entre sí o con valores concretos. El resultado de la comparación es un valor booleano (true o false).
Ejemplo | Nombre | Resultado |
---|---|---|
expresión_1 == expresión_2 | Igual | true si expresión_1 es igual a expresión_2. |
expresión_1 === expresión_2 | Idéntico | true si expresión_1 es igual a expresión_2, y son del mismo tipo. (a partir de PHP 4) |
expresión_1 != expresión_2 | Diferente | true si expresión_1 no es igual a expresión_2. |
expresión_1 <> expresión_2 | ||
expresión_1 !== expresión_2 | No idénticos | true si expresión_1 no es igual a expresión_2, o si no son del mismo tipo. (a partir de PHP 4) |
expresión_1 < expresión_2 | Menor que | true si expresión_1 es estrictamente menor que expresión_2. |
expresión_1 > expresión_2 | Mayor que | true si expresión_1 es estrictamente mayor que expresión_2. |
expresión_1 <= expresión_2 | Menor o igual que | true si expresión_1 es menor o igual que expresión_2. |
expresión_1 >= expresión_2 | Mayor o igual que | true si expresión_1 es mayor o igual que expresión_2. |
Las comparaciones se utilizan por ejemplo en las estructuras de selección if ..., que permiten condicionar la ejecución de unas instrucciones a que el resultado de una expresión sea true.
<?php
$nombre = "Pepe";
if ($nombre == "Juan") {
print "<p>Tu nombre es Juan.</p>\n";
}
if ($nombre != "Juan") {
print "<p>Tu nombre no es Juan.</p>\n";
}
?>
<p>Tu nombre no es Juan.</p>
<?php
$nombrePadre = "Pepe";
$nombreHijo = "Pepe";
if ($nombrePadre == $nombreHijo) {
print "<p>El hijo se llama como el padre.</p>\n";
}
if ($nombrePadre != $nombreHijo) {
print "<p>El hijo no se llama como el padre.</p>\n";
}
?>
<p>El hijo se llama como el padre.</p>
Así como en las asignaciones la variable se escribe siempre a la izquierda de la igualdad, en una comparación las variables pueden aparecer a la derecha de la comparación:.
<?php
$nombre = "Pepe";
if ("Juan" == $nombre) {
print "<p>Tu nombre es Juan.</p>\n";
}
if ("Juan" != $nombre) {
print "<p>Tu nombre no es Juan.</p>\n";
}
?>
<p>Tu nombre no es Juan.</p>
Un error típico cuando se empieza a programar es confundir el operador comparación (==) con el operador de asignación (=), lo que produce resultados inesperados, como en el ejemplo siguiente:
<?php
$nombre = "Pepe";
if ($nombre = "Juan") {
print "<p>Tu nombre es Juan.</p>\n";
}
if ($nombre != "Juan") {
print "<p>Tu nombre no es Juan.</p>\n";
}
?>
<p>Tu nombre es Juan.</p>
Al escribir = en vez de ==, PHP no compara el valor de la variable $nombre con la cadena "Juan", sino que cambia el valor de $nombre a "Juan". Como la asignación no da error, PHP le asigna el valor booleano true, y escribe que el nombre es Juan.
Al no mostrar PHP ningún aviso o mensaje de error, este error puede ser difícil de localizar en programas largos o complejos.
El error contrario, también típico, es escribir una comparación donde debería escribirse una asignación, como en el ejemplo siguiente:
<?php
$nombre = "Pepe";
$nombre == "Juan";
if ($nombre == "Juan") {
print "<p>Tu nombre es Juan.</p>\n";
}
if ($nombre != "Juan") {
print "<p>Tu nombre no es Juan.</p>\n";
}
?>
<p>Tu nombre no es Juan.</p>
Al escribir == en vez de =, PHP no modifica el valor de la variable a la cadena "Pepe", sino que compara el valor de $nombre con "Juan". El resultado de la comparación es true, pero como la instrucción es únicamente una comparación, PHP no realiza ninguna acción aparte de calcular el resultado de la comparación. En la comparaciones de las estructuas if ... siguientes, la variable $nombre sigue teniendo el valor "Pepe".
Al no mostrar PHP ningún aviso o mensaje de error, este error también puede ser difícil de localizar en programas largos o complejos.
No se pueden acumular comparaciones directamente:
<?php
$entero = 6;
$cadena = "6";
$decimal = 6.0;
if ($entero == $cadena == $decimal) {
print "<p>$entero, $cadena y $decimal son iguales.</p>\n";
} else {
print "<p>$entero, $cadena y $decimal son distintos.</p>\n";
}
?>
Parse error: syntax error, unexpected '==' (T_IS_EQUAL) in prueba.php on line 6
En estos casos habría que concatenar comparaciones mediante operadores lógicos, como se explica en el apartado siguiente.
<?php
$entero = 6;
$cadena = "6";
$decimal = 6.0;
if ($entero == $cadena && $entero == $decimal) {
print "<p>$entero, $cadena y $decimal son iguales.</p>\n";
} else {
print "<p>$entero, $cadena y $decimal son distintos.</p>\n";
}
?>
<p>6, 6 y 6 son iguales.</p>
Hay que tener cuidado al comparar expresiones de tipos diferentes, ya que se pueden producir resultados inesperados.
PHP permite comparar expresiones de tipos distintos, y la comparación es correcta siempre que sea posible interpretar un dato de un tipo como un dato de otro tipo.
<?php
$entero = 5;
$decimal = 5.0;
if ($entero == $decimal) {
print "<p>$entero y $decimal son iguales.</p>\n";
} else {
print "<p>$entero y $decimal son distintos.</p>\n";
}
?>
<p>5 y 5 son iguales.</p>
<?php
$numero = 5;
$cadena = "5";
if ($numero == $cadena) {
print "<p>$numero y $cadena son iguales.</p>\n";
} else {
print "<p>$numero y $cadena son distintos.</p>\n";
}
?>
<p>5 y 5 son iguales.</p>
<?php
$numero = 4 + 1;
$cadena = "4 + 1";
if ($numero == $cadena) {
print "<p>$numero y $cadena son iguales.</p>\n";
} else {
print "<p>$numero y $cadena son distintos.</p>\n";
}
?>
<p>5 y 4 + 1 son distintos.</p>
<?php
$numero = 5;
$cadena = " 5 ";
if ($numero == $cadena) {
print "<p>$numero y $cadena son iguales.</p>\n";
} else {
print "<p>$numero y $cadena son distintos.</p>\n";
}
?>
<p>5 y 5 son iguales.</p>
<?php
$numero = 0;
$cadena = "";
if ($numero == $cadena) {
print "<p>$numero y $cadena son iguales.</p>\n";
} else {
print "<p>$numero y $cadena son distintos.</p>\n";
}
?>
<p>0 y son distintos.</p>
Para evitar problemas con las conversiones automáticas de tipo se pueden utilizar los operadores === o !==. La diferencia entre estos operadores y los operadores == y != es que aquellos comprueban además si los tipos son iguales.
<?php
$numero = 5;
$texto = "5";
if ($numero == $texto) {
print "<p>Las variables son iguales.</p>\n";
}
if ($numero != $texto) {
print "<p>Las variables no son iguales.</p>\n";
}
?>
<p>Las variables son iguales.</p>
<?php
$numero = 5;
$texto = "5";
if ($numero === $texto) {
print "<p>Las variables son idénticas.</p>\n";
}
if ($numero !== $texto) {
print "<p>Las variables no son idénticas.</p>\n";
}
?>
<p>Las variables no son idénticas.</p>
Los operadores lógicos son las operaciones que trabajan con valores booleanos y permiten combinar expresiones simples para formar expresiones más complejas.
Operador | Nombre | Resultado |
---|---|---|
expresión_1 && expresión_2 | Y | true si los dos, expresión_1 y expresión_2, son true. |
expresión_1 || expresión_2 | O | true si uno de los dos, expresión_1 o expresión_2, es true. |
!expresión | Negación | true si expresión no es true. |
<?php
print "<p>true && true = " . var_export(true && true, 1) . "</p>\n";
print "\n";
print "<p>true && false = " . var_export(true && false, 1) . "</p>\n";
print "\n";
print "<p>false && true = " . var_export(false && true, 1) . "</p>\n";
print "\n";
print "<p>false && false = " . var_export(false && false, 1) . "</p>\n";
print "\n";
?>
<p>true && true = true</p>
<p>true && false = false</p>
<p>false && true = false</p>
<p>false && false = false</p>
<?php
print "<p>true || true = " . var_export(true || true, 1) . "</p>\n";
print "\n";
print "<p>true || false = " . var_export(true || false, 1) . "</p>\n";
print "\n";
print "<p>false || true = " . var_export(false || true, 1) . "</p>\n";
print "\n";
print "<p>false || false = " . var_export(false || false, 1) . "</p>\n";
print "\n";
?>
<p>true || true = true</p>
<p>true || false = true</p>
<p>false || true = true</p>
<p>false || false = false</p>
Nota: En el lenguaje cotidiano, el "o" se utiliza a menudo en situaciones en las que sólo puede darse una de las dos alternativas. Por ejemplo, en un menú de restaurante se puede elegir "postre o café", pero no las dos cosas (salvo que se pague aparte, claro). En lógica, ese tipo de "o" se denomina "o exclusivo" (xor).
<?php
print "<p>!true = " . var_export(!true, 1) . "</p>\n";
print "\n";
print "<p>!false = " . var_export(!false, 1) . "</p>\n";
print "\n";
?>
<p>!true = false</p>
<p>!false = true</p>
En las expresiones lógicas compuestas hay que prestar atención al orden en que se realizan las operaciones. De la misma manera que en las expresiones aritméticas las multiplicaciones o divisiones se efectúan antes de las sumas o las restas, en las operaciones lógicas se evalúan primero las negaciones (!), luego los "y" (&&) y por último los "o" (||).
Por supuesto, ese orden se puede alterar añadiendo paréntesis en las expresiones, ya que las operaciones entre paréntesis se realizan antes que las operaciones fuera de los paréntesis. En los ejemplos siguientes se comprueba el orden en que se realizan las operaciones comparando los resultados sin paréntesis o con paréntesis:
<?php
print "<p>!true && false = " . var_export(!true && false, 1) . "</p>\n";
print "\n";
print "<p>(!true) && false = " . var_export((!true) && false, 1) . "</p>\n";
print "\n";
print "<p>!(true && false) = " . var_export(!(true && false), 1) . "</p>\n";
print "\n";
?>
<p>!true && false = = false</p>
<p>(!true) && false = = false</p>
<p>!(true && false) = = true</p>
<?php
print "<p>!false || true = " . var_export(!false || true, 1) . "</p>\n";
print "\n";
print "<p>(!false) || true = " . var_export((!false) || true, 1) . "</p>\n";
print "\n";
print "<p>!(false || true) = " . var_export(!(false || true), 1) . "</p>\n";
print "\n";
?>
<p>!false || true = true</p>
<p>(!false) || true = true</p>
<p>!(false || true) = false</p>
<?php
print "<p>false && true || true = " . var_export(false && true || true, 1) . "</p>\n";
print "\n";
print "<p>(false && true) || true = " . var_export((false && true) || true, 1) . "</p>\n";
print "\n";
print "<p>false && (true || true) = " . var_export(false && (true || true), 1) . "</p>\n";
print "\n";
?>
<p>false && true || true = true</p>
<p>(false && true) || true = true</p>
<p>false && (true || true) = false</p>
<?php
print "<p>true || true && false = " . var_export(true || true && false, 1) . "</p>\n";
print "\n";
print "<p>true || (true && false) = " . var_export(true || (true && false), 1) . "</p>\n";
print "\n";
print "<p>(true || true) && false = " . var_export((true || true) && false, 1) . "</p>\n";
print "\n";
?>
<p>true || true && false = true</p>
<p>true || (true && false) = true</p>
<p>(true || true)&& false = false</p>
Cuando las expresiones que se combinan son comparaciones, no es necesario utilizar paréntesis, ya que las comparaciones se realizan antes de las operaciones lógicas
<?php
$a = 10;
$b = -20;
if ($a > 0 && $b > 0) {
print "<p>\$a y \$b son los dos positivos.</p>\n";
} else {
print "<p>\$a y \$b NO son los dos positivos.</p>\n";
}
?>
<p>$a y $b NO son los dos positivos.</p>
En PHP también existen los operadores and ("y" lógico), or ("o" lógico) y xor ("o" exclusivo lógico) que realizan las operaciones lógicas correspondientes:
Operador | Nombre | Resultado |
---|---|---|
expresión_1 and expresión_2 | Y | true si los dos, expresión_1 y expresión_2, son true. |
expresión_1 or expresión_2 | O | true si uno de los dos, expresión_1 o expresión_2, es true. |
expresión_1 xor expresión_2 | O exclusivo | true si solo una de las expresiones es true. |
NO se recomienda utilizar estos operadores, porque tienen menos precedencia que el operador de asignación = y los resultados pueden no ser los esperados, como muestran los siguientes ejemplos.
El ejemplo siguiente muestra el resultado esperado: como $var1 es true, pero $var2 es false, $todo toma el valor false.
<?php
$var1 = true;
$var2 = false;
$todo = $var1 && $var2;
if ($todo) {
print "<p>verdadero</p>\n";
} else {
print "<p>falso</p>\n";
}
?>
<p>falso</p>
Sin embargo si se utiliza el operador and en vez de &&, el resultado no es el esperado:
<?php
$var1 = true;
$var2 = false;
$todo = $var1 and $var2;
if ($todo) {
print "<p>verdadero</p>\n";
} else {
print "<p>falso</p>\n";
}
?>
<p>verdadero</p>
¿Por qué se produce ese resultado? Porque el operador de asignación = tiene precedencia sobre el operador and. Eso quiere decir que PHP realiza antes la asignación que la operación lógica, es decir, como si la expresión estuviese escrita así:
($todo = $var1) and $var2;
<p>verdadero</p>
En esa expresión, la variable $todo almacena el valor de la variable $var1 (true), por lo que $todo toma el valor true. La operación lógica and no modifica el valor de $todo.
Si se quiere obtener el mismo resultado con and que con &&, se deben utilizar paréntesis, para forzar que la operación lógica and se realice antes de la asignación:
<?php
$var1 = true;
$var2 = false;
$todo = ($var1 and $var2);
if ($todo) {
print "<p>verdadero</p>\n";
} else {
print "<p>falso</p>\n";
}
?>
<p>falso</p>