PHP 7.0.6 Released

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 9 notes

up
58
Antistone
2 years ago
BEWARE:  Addition, subtraction, and string concatenation have equal precedence!
<?
$x
= 4;
echo
"x minus one equals " . $x-1 . ", or so I hope";
?>
will print "-1, or so I hope"

(Concatenate the first string literal and the value of $x, then implicitly convert that to a number (zero) so you can subtract 1 from it, then concatenate the final string literal.)
up
26
fabmlk
11 months 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
5
karlisd at gmail dot com
5 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
8
nicoolasens at gmail dot com
6 months ago
Too add something ton Antistone's comment :
{Antistone ¶
1 year ago
BEWARE:  Addition, subtraction, and string concatenation have equal precedence!
<?
$x
= 4;
echo
"x minus one equals " . $x-1 . ", or so I hope";
?>
will print "-1, or so I hope"

(Concatenate the first string literal and the value of $x, then implicitly convert that to a number (zero) so you can subtract 1 from it, then concatenate the final string literal.)
}

You can use the operator "," instead of ".".
This way allows you to concatenate the first string literal after $x-1.
So the first string literal is note convert to a number (zero) .
Solution :

<?php
$x
= 4;
echo
"x minus one equals " , $x-1 . ", or so I hope";
?>

will print :
"x minus one equals 3, or so I hope "
up
25
Carsten Milkau
3 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
5
headden at karelia dot ru
6 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
2
Bilal Mustafa
16 days ago
Another way to sort out the problem mentioned by "nicoolasens at gmail dot com" and "Antistone" is:

<?php
$x
= 4;
echo
"x minus one equals " . $x-1 . ", or so I hope";
?>
will print "-1, or so I hope"

Solution:

We can wrap the methematical part in "()" and let the parser tell to solve it first in other words here we can get the benefit of higher precedence of "()" So if we rewrite the example as:

<?php
$x
= 4;
echo
"x minus one equals " . ($x-1) . ", or so I hope";
?>

The answer will be according to our expectation which is:

"x minus one equals 3, or so I hope"
up
1
leipie at gmail dot com
2 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
-1
Anonymous
11 months 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