Precedencia de operadores
La precedencia de un operador indica qué tan "estrechamente" se unen dos
expresiones juntas. Por ejemplo, en la expresión 1 +
5 * 3
, la respuesta es 16
y no
18
porque el operador de multiplicación ("*")
tiene una precedencia mayor que el operador de adición ("+").
Los paréntesis pueden ser usados para forzar la precedencia, si es necesario. Por
ejemplo: (1 + 5) * 3
se evalúa como
18
.
Cuando los operadores tienen igual precedencia su asociatividad decide
cómo se agrupan. Por ejemplo "-" tiene asociatividad a izquierda, así
1 - 2 - 3
se agrupa como (1 - 2) - 3
y se evalúa a -4
. "=", por otra parte, tiene
asociatividad a derecha, así $a = $b = $c
se agrupa como
$a = ($b = $c)
.
Los operadores de igual precedencia que no son asociativos no pueden usarse
unos junto a otros, por ejemplo, 1 < 2 > 1
es
ilegal en PHP. La expresión 1 <= 1 == 1
, por otro
lado, es legal, ya que el operador ==
tiene menos
precedencia que el operador <=
.
El uso de paréntesis, incluso cuando no es estrictamente necesario, a menudo puede
aumentar la legibilidad del código haciendo grupos explícitamente en lugar de confiar
en la precedencia y asociatividad implícitas del operador.
La siguiente tabla enumera los operadores en orden de precedencia, con
los de más alta precedencia al inicio. Los operadores en la misma línea
tienen igual precedencia, en cuyo caso la asociatividad decide el agrupamiento.
Ejemplo #1 Asociatividad
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
// la asociatividad del operador ternario difiere de C/C++
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>
La precedencia y asociatividad de los operadores solamente determinan cómo
se agrupan las expresiones, no especifican un orden de evaluación. PHP no
especifica (en general) el orden en que se evalúa una expresión
y se debería evitar el código que se asume un orden específico de evaluación,
ya que el comportamiento puede cambiar entre versiones de PHP o dependiendo de
código circundante.
Ejemplo #2 Orden de evaluación no definido
<?php
$a = 1;
echo $a + $a++; // podría mostrar 2 o 3
$i = 1;
$array[$i] = $i++; // podría establecer el índice a 1 o 2
?>
Ejemplo #3 +
, -
y .
tienen la misma precedencia
<?php
$x = 4;
// esta línea podría resultar en una salida inesperada:
echo "x menos uno igual a " . $x-1 . ", o eso espero\n";
// ya que se evalúa como esta línea:
echo (("x menos uno igual a " . $x) - 1) . ", o eso espero\n";
// la precedencia deseada se puede forzar con paréntesis:
echo "x menos uno igual a " . ($x-1) . ", o eso espero\n";
?>
El resultado del ejemplo sería:
-1, o eso espero
-1, o eso espero
x menos uno igual a 3, o eso espero
Nota:
Aunque =
tiene una precedencia menor que
la mayoría de los demás operadores, PHP aun permitirá expresiones
similares a lo siguiente: if (!$a = foo())
,
en cuyo caso el valor devuelto de foo()
es
puesto en $a.