運(yùn)算符優(yōu)先級

運(yùn)算符優(yōu)先級指定了兩個(gè)表達(dá)式綁定得有多“緊密”。例如,表達(dá)式 1 + 5 * 3 的結(jié)果是 16 而不是 18 是因?yàn)槌颂枺ā?”)的優(yōu)先級比加號(“+”)高。必要時(shí)可以用括號來強(qiáng)制改變優(yōu)先級。例如:(1 + 5) * 3 的值為 18。

如果運(yùn)算符優(yōu)先級相同,那運(yùn)算符的結(jié)合方向決定了該如何運(yùn)算。例如,"-"是左聯(lián)的,那么 1 - 2 - 3 就等同于 (1 - 2) - 3 并且結(jié)果是 -4. 另外一方面,"="是右聯(lián)的,所以 $a = $b = $c 等同于 $a = ($b = $c)。

沒有結(jié)合的相同優(yōu)先級的運(yùn)算符不能連在一起使用,例如 1 < 2 > 1 在PHP是不合法的。但另外一方面表達(dá)式 1 <= 1 == 1 是合法的, 因?yàn)?== 的優(yōu)先級低于 <=。

關(guān)聯(lián)性僅對二(三)元操作符有意義。 一元操作符是前綴或者后綴,所以不適用該概念。 例如 !!$a 僅可分為 !(!$a)

括號的使用,哪怕在不是必要的場合下,通過括號的配對來明確標(biāo)明運(yùn)算順序,而非靠運(yùn)算符優(yōu)先級和結(jié)合性來決定,通常能夠增加代碼的可讀性。

下表按照優(yōu)先級從高到低列出了運(yùn)算符。同一行中的運(yùn)算符具有相同優(yōu)先級,此時(shí)它們的結(jié)合方向決定求值順序。

運(yùn)算符優(yōu)先級
結(jié)合方向 運(yùn)算符 附加信息
不適用 clone new clonenew
** 算術(shù)運(yùn)算符
不適用 + - ++ -- ~ (int) (float) (string) (array) (object) (bool) @ 算術(shù) (一元 +-), 遞增/遞減, 按位, 類型轉(zhuǎn)換錯誤控制
instanceof 類型
不適用 ! 邏輯運(yùn)算符
* / % 算術(shù)運(yùn)算符
+ - . 算數(shù) (二元 +-), arraystring. PHP 8.0.0 前可用)
<< >> 位運(yùn)算符
. string (PHP 8.0.0 起可用)
< <= > >= 比較運(yùn)算符
== != === !== <> <=> 比較運(yùn)算符
& 位運(yùn)算符引用
^ 位運(yùn)算符
| 位運(yùn)算符
&& 邏輯運(yùn)算符
|| 邏輯運(yùn)算符
?? null 合并運(yùn)算符
無關(guān)聯(lián) ? : 三元運(yùn)算符 (PHP 8.0.0 之前左聯(lián))
= += -= *= **= /= .= %= &= |= ^= <<= >>= ??= 賦值運(yùn)算符
不適用 yield from yield from
不適用 yield yield
不適用 print print
and 邏輯運(yùn)算符
xor 邏輯運(yùn)算符
or 邏輯運(yùn)算符

示例 #1 結(jié)合方向

<?php
$a 
5// (3 * 3) % 5 = 4
// PHP 的三元操作符跟 C/C++ 有區(qū)別
$a true true 2// (true ? 0 : true) ? 1 : 2 = 2 (PHP 8.0.0 前可用)

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

運(yùn)算符優(yōu)先級和關(guān)聯(lián)方式僅決定表達(dá)式如何分組,不指定計(jì)算順序。 一般情況下, PHP 不指定表達(dá)式的計(jì)算順序,并且代碼避免指定假設(shè)執(zhí)行順序, 因?yàn)樾袨闀?PHP 版本間發(fā)生變化或者依賴于旁邊的代碼。

示例 #2 未定義執(zhí)行順序

<?php
$a 
1;
echo 
$a $a++; // 可能會輸出 2 或 3

$i 1;
$array[$i] = $i++; // 可能會設(shè)置索引 1 或 2
?>

示例 #3 +- 、. 具有相同的優(yōu)先級

<?php
$x 
4;
// 這行可能會導(dǎo)致不可預(yù)料的輸出:
echo "x minus one equals " $x-", or so I hope\n";
// 因?yàn)樗沁@樣計(jì)算的:(PHP 8.0.0 之前版本)
echo (("x minus one equals " $x) - 1) . ", or so I hope\n";
// 可以使用括號來強(qiáng)制指定優(yōu)先級:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>

以上例程會輸出:

-1, or so I hope
-1, or so I hope
x minus one equals 3, or so I hope

注意:

盡管 = 比其它大多數(shù)的運(yùn)算符的優(yōu)先級低,PHP 仍舊允許類似如下的表達(dá)式:if (!$a = foo()),在此例中 foo() 的返回值被賦給了 $a

更新日志

版本 說明
8.0.0 現(xiàn)在,字符串連接符(.)的優(yōu)先級比算數(shù)加/減(+-)、按位左/右移(<<>>)更低。在此之前,它的優(yōu)先級與 +- 相同,并且比 <<、 >> 更高。
8.0.0 三元運(yùn)算符(? :)是現(xiàn)在是非關(guān)聯(lián)的;以前它是左聯(lián)的。
7.4.0 已棄用在無括號的表達(dá)式中依賴字符串連接(.)相對于算數(shù)加/減(+ 或者 -)或者按位左/右移(<< 或者 >>)的優(yōu)先級的使用方法。
7.4.0 不推薦使用三元運(yùn)算符(? :)的左聯(lián)。 即已棄用嵌套多個(gè)未帶括號的三元運(yùn)算符。