Operator Precedence
Оновлено: 11.05.2023
Пріоритет оператора визначає, наскільки "міцно" він пов'язує два вирази разом. Наприклад, у виразі 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 є легальним, оскільки оператор == має нижчий пріоритет, ніж оператор <=.
Асоціативність має сенс лише для бінарних (і тернарних) операторів. Унарні оператори є або префіксними, або постфіксними, тому це поняття не застосовується. Наприклад, !!$a можна згрупувати лише як !(!$a).
Використання круглих дужок, навіть коли це не є обов'язковим, часто може покращити читабельність коду, роблячи групування явним, а не покладаючись на неявні оператори пріоритету та асоціативності.
У наступній таблиці перераховані оператори в порядку пріоритету, з операторами з найвищим пріоритетом зверху. Оператори в одному рядку мають однаковий пріоритет, у цьому випадку асоціативність визначає групування.
clone
new
**+
-
++
--
~
(int)
(float)
(string)
(array)
(object)
(bool)
@
+ and -),
increment/decrement,
bitwise,
type casting and
error control
instanceof!*
/
%
+
-
.
+ and -),
array and
string (. prior to PHP 8.0.0)
<<
>>
.<
<=
>
>=
==
!=
===
!==
<>
<=>
&^|&&||??? :=
+=
-=
*=
**=
/=
.=
%=
&=
|=
^=
<<=
>>=
??=
yield fromyieldprintandxororПриклад №1 Асоціативність
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
// ternary operator associativity differs from C/C++
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2 (prior to PHP 8.0.0)
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>
Оператори пріоритету та асоціативності визначають лише спосіб групування виразів, вони не визначають порядок обчислення. PHP не визначає (у загальному випадку), в якому порядку обчислюється вираз, і слід уникати коду, який передбачає певний порядок обчислення, оскільки поведінка може змінюватися між версіями PHP або в залежності від оточуючого коду.
Приклад #2 Невизначений порядок оцінювання
<?php
$a = 1;
echo $a + $a++; // may print either 2 or 3
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>
Приклад #3 +, - та . мають однаковий пріоритет (до версії PHP 8.0.0)
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";
// because it is evaluated like this line (prior to PHP 8.0.0):
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>
Вищенаведений приклад виведе:
Зауважте:
Хоча = має нижчий пріоритет, ніж більшість інших операторів, PHP все одно допускає вирази, подібні до наступного: if (!$a = foo()), в якому значення, що повертається функцією foo(), поміщається в $a.
.) now has a lower precedence than
arithmetic addition/subtraction (+ and -) and
bitwise shift left/right (<< and >>);
previously it had the same precedence as + and -
and a higher precedence than << and >>.
? :) is non-associative now;
previously it was left-associative.
.) relative to
arithmetic addition/subtraction (+ or -) or
bitwise shift left/right (<< or >>),
i.e. using them together in an unparenthesized expression, is deprecated.
? :),
i.e. nesting multiple unparenthesized ternary operators, is deprecated.