Приоритет оператора

Приоритет оператора определяет, насколько "тесно" он связывает между собой два выражения. Например, выражение 1 + 5 * 3 вычисляется как 16, а не 18, поскольку оператор умножения ("*") имеет более высокий приоритет, чем оператор сложения ("+"). Круглые скобки могут использоваться для принудительного указания порядка выполнения операторов. Например, выражение (1 + 5) * 3 вычисляется как 18.

Если операторы имеют равный приоритет, то их группирование определяется их ассоциативностью. Например "-" имеет левую ассоциативность, поэтому 1 - 2 - 3 группируется как (1 - 2) - 3 и равно -4. С другой стороны, "=" имеет правую ассоциативность, поэтому $a = $b = $c группируется как $a = ($b = $c).

Операторы с равным приоритетом, но не имеющие ассоциативность, не могут использоваться вслед друг за другом, например 1 < 2 > 1 недопустимо в PHP. С другой стороны, выражение 1 <= 1 == 1 вполне допустимо, так как оператор == имеет меньший приоритет чем оператор <=.

Используйте скобки, даже если они не обязательны. Чаще всего это повышает читаемость кода, непосредственно определяя порядок группировки, не полагаясь на конкретные приоритет или ассоциативность оператора.

В следующей таблице приведен список операторов, отсортированный по убыванию их приоритетов. Операторы, размещенные в одной строке имеют одинаковый приоритет и их группировка при выполнении определяется исходя из их ассоциативности.

Порядок выполнения операторов
Ассоциативность Оператор Дополнительная информация
неассоциативна clone new clone и new
левая [ array()
правая ** арифметика
правая ++ -- ~ (int) (float) (string) (array) (object) (bool) @ типы и инкремент/декремент
неассоциативна instanceof типы
правая ! логические операторы
левая * / % арифметические операторы
левая + - . арифметические операторы и строковые операторы
левая << >> побитовые операторы
неассоциативна < <= > >= операторы сравнения
неассоциативна == != === !== <> операторы сравнения
левая & побитовые операторы и ссылки
левая ^ побитовые операторы
левая | побитовые операторы
левая && логические операторы
левая || логические операторы
левая ? : тернарный оператор
правая = += -= *= **= /= .= %= &= |= ^= <<= >>= => операторы присваивания
левая and логические операторы
левая xor логические операторы
левая or логические операторы
левая , множество применений

Пример #1 Ассоциативность

<?php
$a 
5// (3 * 3) % 5 = 4
// ассоциативность тройного оператора отличается от 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
?>

приоритет и ассоциативность оператора определяет только группировку выражений, и не определяет порядок выполнения. PHP (в целом) не описывает в каком порядке выражение выполняется, и следует избегать код, опирающийся на порядок выполнения, так как поведение может меняться между версиями PHP в зависимости от окружающего кода.

Пример #2 Неизвестный порядок выполнения

<?php
$a 
1;
echo 
$a $a++; // может вывести и 2 и 3

$i 1;
$array[$i] = $i++; // может задать как индекс 1, так и 2
?>

Замечание:

Несмотря на то, что оператор = имеет низший приоритет, чем большинство остальных операторов, PHP все равно позволяет использовать следующую конструкцию: if (!$a = foo()), которая присваивает переменной $a результат выполнения функции foo().

Коментарии

Автор:
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  == 1do_something(); ?>

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

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

in PHP instead.
2012-07-06 15:06:54
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
Автор:
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.
2015-06-02 20:41:22
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
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.
2015-11-10 19:39:51
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
<?php 
// Another tricky thing here is using && or || with ternary ?:
$x && $y $a $b// ($x && $y) ? $a : $b;

// while:
$x and $y $a $b// $x and ($y ? $a : $b);

?>
2017-04-24 18:55:49
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
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 "...".

For a really comprehensive list, take a look at the "List of Parser Tokens" page: tokens
2017-08-11 04:18:29
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
Three types of operator associativity in php.
1.left
2.rigt
3.non-associativity

Category of three operators are right associativity
1)**
2)=,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>=,??=,.=
3)??

Category of eight operators are non-associativity
1)clone new
2)++,--,~,@
3)!
4)<,<=,>,>=
5)<<,>>
6)yield from
7)yield
8)print

Rest of the operators are left associativity
2021-02-01 05:36:50
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
//incorrect
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
//Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` 
//correct
$a = (true ? 0 : true) ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2

==> correction documentation.
2021-02-20 23:44:17
http://php5.kiev.ua/manual/ru/language.operators.precedence.html
An easy trick to get the result of the left shift operation (<<), e.g.

15 << 2 = 15 * (2*2) = 60

15 << 3 = 15 * (2*2*2) = 120

15 << 5 = 15 * (2*2*2*2*2) = 480

and so on...

So it's:

(number on left) multiplied by (number on right) times 2.

The same goes for the right shift operator (>>), where:

(number on left) divided by (number on right) times 2 e.g.

15 >> 2 = (15/2)/2 = 7/2 = 3 (use floor values if result is in decimals).

35 >> 3 = (((35/2)/2)/2 = (17/2)/2 = 8/2 = 4
2021-09-05 00:58:58
http://php5.kiev.ua/manual/ru/language.operators.precedence.html

    Поддержать сайт на родительском проекте КГБ