A precedência de um operador especifica quem tem mais prioridade quando há
duas delas juntas. Por exemplo, na expressão 1 +
5 * 3, a resposta é 16 e não
18 porque o operador de multiplicação ("*")
tem prioridade de precedência que o operador de adição ("+").
Parênteses podem ser utilizados para forçar a precedência, se necessário.
Assim, (1 + 5) * 3 é avaliado como
18.
Quando operadores têm precedência igual a associatividade decide
como os operadores são agrupados. Por exemplo "-" é associado à esquerda, de forma que
1 - 2 - 3 é agrupado como (1 - 2) - 3
e resulta em -4. "=" por outro lado
associa para a direita, de forma que $a = $b = $c é agrupado como
$a = ($b = $c).
Operadores de igual precedência e associatividade não podem
ser utilizados uns próximos aos outros. Por exemplo 1 < 2 > 1 é
ilegal no PHP. A expressão 1 <= 1 == 1 por outro
lado é válida, porque o operador == tem menor
precedência que o operador <=.
A associatividade somente faz sentido para operadores binários e ternários.
Operadores unários são precedentes ou seguintes, de forma que essa outra noção não se aplica.
Por exemplo !!$a somente pode ser agrupado como !(!$a).
O uso de parênteses, embora não estritamente necessário, pode melhorar
a leitura do código ao deixar o agrupamento explícito em vez de depender
da associatividade e precedências implícitos.
A tabela seguinte mostra a precedência dos operadores, com a maior
precedência no começo. Operadores com a mesma precedência estão na mesma linha,
nesses casos a associatividade deles decidirá qual ordem eles serão avaliados.
// isto não é permitido desde o PHP 8 // $a = true ? 0 : true ? 1 : 2; ?>
A precedência e associatividade apenas determinam como as expressões são
agrupadas, mas não especificam a ordem de avaliação. O PHP
(geralmente) não especifica em que ordem as expressões são avaliadas,
então códigos que assumem ordens específicas de avaliação devem ser evitados
porque o comportamento pode ser alterado entre versões do PHP ou dependendo
do código em volta.
Exemplo #3 Ordem de avaliação não definida
<?php $a = 1; echo $a + $a++; // pode exibir 2 ou 3
$i = 1; $array[$i] = $i++; // pode definir o índice 1 ou 2 ?>
Exemplo #4 Precedência de +, - e .
<?php $x = 4; // esta linha pode resultar em uma saída inesperada: echo "x menos um é igual a " . $x-1 . ", ou assim eu espero\n";
// a precedência desejada pode ser aplicada utilizando parênteses: echo "x menos um é igual a " . ($x-1) . ", ou assim eu espero\n";
// isto não é permitido e lança um TypeError: echo (("x menos um é igual a " . $x) - 1) . ", ou assim eu espero\n"; ?>
O exemplo acima produzirá:
-1, ou assim eu espero
-1, ou assim eu espero
Fatal error: Uncaught TypeError: Unsupported operand types: string - int
Exemplo #5 Antes do PHP 8, +, - e . tinham a mesma precedência
<?php $x = 4; // this line might result in unexpected output: echo "x menos um é igual a " . $x-1 . ", ou assim eu espero\n";
// porque é avaliada como esta linha (antes do PHP 8.0.0): echo (("x menos um é igual a " . $x) - 1) . ", ou assim eu espero\n";
// a precedência desejada pode ser aplicada utilizando parênteses: echo "x menos um é igual a " . ($x-1) . ", ou assim eu espero\n"; ?>
O exemplo acima produzirá:
-1, ou assim eu espero
-1, ou assim eu espero
x menos um é igual a 3, ou assim eu espero
Nota:
Embora o = tenha uma precedência menor que
a maioria dos operadores, o PHP ainda permite expressões
similares a if (!$a = foo()),
onde o valor retornado de foo() é
colocado em $a.
Registro de Alterações
Versão
Descrição
8.0.0
Concatenação de strings (.) tem uma precedência menor que
adição/subtração (+ e -) e
shift de bits à esquerda/direita (<< e >>);
anteriormente ele tinha a mesma precedência que + e -
uma precedência maior que << e >>.
8.0.0
O operador ternário (? :) agora é não associativo;
anteriormente associava a esquerda.
7.4.0
Depender da precedência da concatenação de strings (.) em relação
à adição/subtração (+ ou -) ou
shift de bits a esquerda/direta (<< ou >>),
ou seja, os usar numa mesma expressão, foi descontinuado.
7.4.0
Depender da associatividade à esquerda do operador ternário (? :),
ou seja, o utilizar em várias expressões sem parênteses, foi descontinuado.
If you've come here looking for a full list of PHP operators, take note that the table here is *not* complete. There are some additional operators (or operator-ish punctuation tokens) that are not included here, such as "->", "::", and "...".