Precedência de Operadores

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 tem 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 sem 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 <=.

O uso de parenteses, 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.

Precedência dos operadores
Associação Operadores Informação Adicional
não associativo clone new clone e new
esquerda [ array()
direita ** aritmética
direita ++ -- ~ (int) (float) (string) (array) (object) (bool) @ types e incremento/decremento
não associativo instanceof tipos
direita ! lógicos
esquerda * / % aritmética
esquerda + - . aritmética e string
esquerda << >> bits
não associativo < <= > >= comparação
não associativo == != === !== <> <=> comparação
esquerda & bits e referências
esquerda ^ bits
esquerda | bits
esquerda && lógicos
esquerda || lógicos
direita ?? comparação
esquerda ? : ternário
direita = += -= *= **= /= .= %= &= |= ^= <<= >>= atribuição
esquerda and lógicos
esquerda xor lógicos
esquerda or lógicos

Exemplo #1 Associação

<?php
$a 
5// (3 * 3) % 5 = 4
// associação do operador ternário difere do C/C++
$a true true 2// (true ? 0 : true) ? 1 : 2 = 2

$a 1;
$b 2;
$a $b += 3// $a = ($b += 3) -> $a = 5, $b = 5
?>

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 #2 Ordem de avaliação não definida

<?php
$a 
1;
echo 
$a $a++; // pode imprimir 2 ou 3

$i 1;
$array[$i] = $i++; // pode definir o índice 1 ou 2
?>

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.

add a note add a note

User Contributed Notes 6 notes

up
34
fabmlk
1 year ago
Watch out for the difference of priority between 'and vs &&' or '|| vs or':
<?php
$bool
= true && false;
var_dump($bool); // false, that's expected

$bool = true and false;
var_dump($bool); // true, ouch!
?>
Because 'and/or' have lower priority than '=' but '||/&&' have higher.
up
28
Carsten Milkau
4 years ago
Beware the unusual order of bit-wise operators and comparison operators, this has often lead to bugs in my experience. For instance:

<?php if ( $flags & MASK  == 1) do_something(); ?>

will not do what you might expect from other languages. Use

<?php if (($flags & MASK) == 1) do_something(); ?>

in PHP instead.
up
4
karlisd at gmail dot com
10 months ago
Sometimes it's easier to understand things in your own examples.
If you want to play around operator precedence and look which tests will be made, you can play around with this:

<?php
function F($v) {echo $v." "; return false;}
function
T($v) {echo $v." "; return true;}

IF (
F(0) || T(1) && F(2)  || F(3)  && ! F(4) ) {
  echo
"true";
} else echo
" false";
?>
Now put in IF arguments f for false and t for true, put in them some ID's. Play out by changing "F" to "T" and vice versa, by keeping your ID the same. See output and you will know which arguments  actualy were checked.
up
4
headden at karelia dot ru
7 years ago
Although example above already shows it, I'd like to explicitly state that ?: associativity DIFFERS from that of C++. I.e. convenient switch/case-like expressions of the form

$i==1 ? "one" :
$i==2 ? "two" :
$i==3 ? "three" :
"error";

will not work in PHP as expected
up
0
leipie at gmail dot com
3 years ago
The precedence of the arrow operator (->) on objects seems to the highest of all, even higher then clone.

But you can't wrap (clone $foo)->bar() like this!
up
-2
Anonymous
1 year ago
The following example will output false
$a = 1;
$b = 1;

$c = $a + $a++;
$d = 1 + $b++;

if($c == $d){
    echo 'true';
}else{
    echo 'false';
}
To Top