Un operador toma uno o más valores y produce uno nuevo: $a + $b suma, $a . $b une cadenas, $a && $b es un AND lógico, $a === $b compara, $i++ incrementa.
/ devuelve un float salvo que dos enteros se dividan de forma exacta: 17 / 5 es 3.4, 10 / 5 es el entero 2. Cuando solo quieras la parte entera, usa intdiv(). El redondeo se explica en la página de matemáticas.
Operadores aritméticos
| Operador | Nombre | Ejemplo | Resultado |
|---|---|---|---|
+ | Suma | 7 + 2 | 9 |
- | Resta | 7 - 2 | 5 |
* | Multiplicación | 7 * 2 | 14 |
/ | División | 7 / 2 | 3.5 |
% | Módulo (resto) | 7 % 2 | 1 |
** | Potencia | 7 ** 2 | 49 |
-$a | Negación | -7 | -7 |
El módulo es útil para "cada N elementos" y para comprobar pares e impares. Su resultado toma el signo del lado izquierdo, y dividir por cero lanza un error que puedes capturar:
Operadores de asignación
= guarda un valor. Cada operador aritmético y de cadena tiene una forma combinada que actualiza una variable en el sitio.
??= pertenece a la familia del operador de fusión de null. Solo asigna cuando la variable no está definida o es null.
Incremento y decremento: ++ y --
$i++ devuelve el valor actual y luego suma 1. ++$i suma 1 y luego devuelve el valor nuevo. La diferencia solo se nota cuando usas el resultado en la misma expresión.
El truco de las letras es como se suelen generar los nombres de columna de una hoja de cálculo (A, B, ... Z, AA).
Operadores lógicos: &&, ||, ! y xor
| Operador | Verdadero cuando |
|---|---|
$a && $b | los dos son verdaderos |
$a || $b | al menos uno es verdadero |
!$a | $a es falso |
$a xor $b | exactamente uno es verdadero |
$a and $b, $a or $b | igual que && y ||, con menos precedencia |
&& y || hacen cortocircuito: el lado derecho no se evalúa cuando el izquierdo ya decide el resultado. Eso es lo que hace segura la expresión isset($user) && $user->isAdmin().
and vs &&: la trampa de la precedencia
and y or tienen menos prioridad que =, así que en una asignación se aplican después de guardar el valor. Es un bug clásico:
La baja precedencia es útil en un modismo, $file = fopen($path, 'r') or die('Cannot open');, donde quieres que la asignación ocurra primero. En cualquier otro sitio, usa && y ||.
Operadores de cadena: . y .=
PHP tiene dos operadores de cadena: . une dos cadenas ("Grace" . " " . "Hopper") y .= añade al final de una variable ($html .= "<li>"). + nunca une cadenas: "3" + "4" es el número 7, mientras que "3" . "4" es la cadena "34". La página de cadenas explica la interpolación y las comillas.
Comparación y el operador nave espacial <=>
== compara después de convertir los tipos, === además comprueba el tipo y <=> devuelve -1, 0 o 1, que es justo lo que necesitan los callbacks de ordenación. Los detalles y la tabla completa de comparación flexible están en la página de operadores de comparación.
Operadores de arrays
+ con arrays es una unión: ganan las claves del array izquierdo y solo se añaden del derecho las claves que faltan. Eso sorprende a quien espera que añada al final. == comprueba los mismos pares clave/valor, y === además exige el mismo orden y los mismos tipos.
Para añadir una lista a otra, usa array_merge() o la sintaxis spread [...$a, ...$b].
Precedencia de operadores
Cuando una expresión mezcla operadores, PHP los aplica en un orden fijo. Los que más confunden, con lo que imprime PHP 8.3:
echo 2 + 3 * 4; // 14: * before +
echo (2 + 3) * 4; // 20
echo 2 ** 3 ** 2; // 512: right to left, 2 ** 9
echo -2 ** 2; // -4: ** before unary minus
echo "Sum: " . 2 + 3; // Sum: 5, since PHP 8 + runs before .
Ante la duda, añade paréntesis. No cuestan nada y quien lea la línea después no tiene que recordar la tabla.
Preguntas frecuentes
¿Cuál es la diferencia entre and y && en PHP?
Los dos son un AND lógico, pero and tiene menos precedencia que =. Así, $x = true and false; guarda true en $x (la asignación ocurre primero), mientras que $x = true && false; guarda false. Usa && y || en las expresiones y deja and/or fuera de las asignaciones.
¿Qué hace % en PHP?
% es el operador módulo: devuelve el resto de una división entera, así que 10 % 3 es 1. El resultado toma el signo del operando izquierdo (-7 % 3 es -1). Para floats usa fmod(), y % 0 lanza un DivisionByZeroError.
¿Cómo elevo un número a una potencia en PHP?
Usa el operador **: 2 ** 10 es 1024. Es asociativo por la derecha, así que 2 ** 3 ** 2 es 2 ** 9 = 512, y tiene más prioridad que el menos unario, así que -2 ** 2 es -4. La función pow(2, 10) hace lo mismo.
¿Cuál es la diferencia entre $i++ y ++$i en PHP?
Los dos suman 1 a $i. $i++ (post-incremento) devuelve el valor anterior y luego incrementa; ++$i (pre-incremento) incrementa primero y devuelve el valor nuevo. En una línea propia, como el paso de un bucle for, no hay diferencia.