PHP 教學 - 運算子 (Operators) - 上
介紹 PHP 中運算子的用法,包含種類、優先順序、算術運算子 (Arithmetic Operator)、指派運算子 (Assignment Operator)、位元運算子 (Bitwise Operator)、比較運算子 (Comparison Operator)、三元運算子 (Ternary Operator)和錯誤控制運算子 (Error Control Operator)。
簡介
種類
透過提供一些數值給運算子 (Operator,或運算符) 進行運算,進而得到一個運算結果,可以想成類似函式的回傳,另外被運算的數值稱為運算元 (Operand)。
依據運算元的個數,運算子可以分為三種:
- 一元運算子,只有一個運算元,例如:
!
,++
等。 - 二元運算子,包含兩個運算元,大部分都屬於這類。
- 三元運算子,包含三個運算元,只有
? :
運算子屬於此類。
而依據性質,可以分為:
- 算術運算子 (Arithmetic Operator)
- 指派運算子 (Assignment Operator)
- 位元運算子 (Bitwise Operator)
- 比較運算子 (Comparison Operator)
- 三元運算子 (Ternary Operator)
- 錯誤控制運算子 (Error Control Operator)
- 執行運算子 (Execution Operator)
- 增值/減值運算子 (Incrementing/Decrementing Operator)
- 邏輯運算子 (Logical Operator)
- 字串運算子 (String Operator)
- 陣列運算子 (Array Operator)
- 型別運算子 (Type Operator)
運算子優先順序
不同的運算子有不同的優先順序 (Precedence),例如:1 + 2 * 3 是 7 而不是 9,乘號 (*
) 的優先順序大於加號 (+
) 而先做。可以利用括號來增加優先順序,例如:(1 + 2) * 3 為 9。如果優先順序相同則依據運算子的結合律 (Associativity) 決定先做左或右邊。以下為運算子由高至低的順序表:
結合律 | 運算子 |
---|---|
無 | clone new |
左 | [ |
右 | ++ – ~ - (int) (float) (string) (array) (object) (bool) @ |
無 | instanceof |
右 | ! |
左 | * / % |
左 | + - . |
左 | << >> |
無 | < <= > >= <> |
無 | == != === !== |
左 | & |
左 | ^ |
左 | | |
左 | && |
左 | || |
左 | ? : |
右 | = += -= *= /= .= %= &= |
左 | and |
左 | xor |
左 | or |
左 | , |
結合律左右的解釋範例如下:
1 | // 結合律: 左 |
但有時候指派 (=
) 雖然順序較後,但仍然會先進行運算:
1 | $a = false; |
算術運算子
算術運算子 (Arithmetic Operator) 就如同數學的四則運算一般,包含以下運算子:
範例 | 名稱 | 說明 |
---|---|---|
-$a | 負號 | 將 $a 正負變號 |
$a + $b | 加法 | $a 和 $b 的總和 |
$a - $b | 減法 | $a 減去 $b |
$a * $b | 乘法 | $a 乘上 $b |
$a / $b | 除法 | $a 除以 $b |
$a % $b | 取餘數 | $a 除以 $b 的餘數 (餘數的正負號與 $a 相同) |
整數除不盡時會轉為浮點數,以及大整數取餘數時可能會有問題,可以參考 PHP 教學 - 資料型態 (Data Type) - 上。
指派運算子
基本的指派運算子 (Assignment Operator) 符號是 (=
),你可能會把它想成數學的等於,但實際上不能這樣想,正確的意思是:將右邊的結果放入左邊。
陣列的宣告時使用 (=>
) 的符號來指派陣列元素的內容。除此之外,指派運算子可以和二元運算子結合使用,用法如下:
$a X=
$b 相當於 $a = $a X
$b,X
代換為任意二元運算子,例如:$a += $b 相當於 $a = $a + $b。
1 | $num = 3; |
位元運算子
位元運算子 (Bitwise Operator) 能夠對整數的位元進行運算,包含以下運算子:
範例 | 名稱 | 說明 |
---|---|---|
$a & $b | 交集 (And) | $a 和 $b 的位元皆為 1 的部份為 1 |
$a | $b | 聯集 (Or) | $a 或 $b 的位元其中一方為 1 的部份為 1 |
$a ^ $b | 互斥 (Xor) | $a 和 $b 的位元只有其中一方為 1 的部份為 1 |
~ $a | 補數 (Not) | $a 為 1 的部份為 0,為 0 的部份為 1 |
$a << $b | 左移 | $a 往左移動 $b 個位元 (意同 $a 乘以 2 的 $b 次方) |
$a >> $b | 右移 | $a 往右移動 $b 個位元 (意同 $a 除以 2 的 $b 次方之整數) |
向左位移時,正負號不會保留;而向右位移時,正負號會保留。進行位元運算時,如果不是整數型別會先轉成整數型別處理,但當兩邊都是字串型別時,會以字元的 ASCII 碼來進行處理 (位移運算除外)。
位移運算的位移量會取平台位元數的餘數進行運算,例如在 32 位元平台的 $a << 33
會轉為 $a << (33 % 32)
相當於 $a << 1
,一些範例如下:
1 | // 只顯示最右邊8個bit |
比較運算子
比較運算子 (Comparison Operator) 可以比較兩個值,並將結果以布林回傳,包含以下運算子:
範例 | 名稱 | 說明 |
---|---|---|
$a == $b | 相等 | 如果 $a 和 $b 的值相等則為 TRUE |
$a === $b | 完全相等 | 如果 $a 和 $b 的值與型別都相等則為 TRUE |
$a != $b | 不相等 | 如果 $a 和 $b 的值不相等則為 TRUE |
$a <> $b | 不相等 | 如果 $a 和 $b 的值不相等則為 TRUE |
$a !== $b | 不完全相等 | 如果 $a 和 $b 的值或型別不相等則為 TRUE |
$a < $b | 小於 | 如果 $a 小於 $b 則為 TRUE |
$a > $b | 大於 | 如果 $a 大於 $b 則為 TRUE |
$a <= $b | 小於等於 | 如果 $a 小於等於 $b 則為 TRUE |
$a >= $b | 大於等於 | 如果 $a 大於等於 $b 則為 TRUE |
如果字串和數字比較或兩個字串皆為數字的形式比較時,字串會先轉為數字後比較,例如:
1 | var_dump(0 == "a"); // bool(true), 轉為數字當作 0 和 0 |
各種型別進行比較時,會根據以下的規則來做處理,情況重疊時以較上方的規則為準:
型別1 | 型別2 | 結果 |
---|---|---|
數字形式字串 | 數字形式字串 | 轉為數字進行比較 。 |
字串 | 字串 | 以字串內容進行比較 。 |
字串 | NULL | NULL 轉為空字串 "" 進行比較 。 |
布林 | 任何型別 | 轉為布林進行比較,且 FALSE < TRUE。 |
物件 | 物件 | 不同類別無法比較,相同類別在 PHP 4 比較方式和陣列一樣,在 PHP 5 中更為複雜,在之後的章節再做討論。 |
實作 toString 物件 | 任何型別 | 以 toString() 結果字串進行比較,與字串比較規則相同。 |
物件 | 字串 | 物件永遠比較大。 |
陣列 | 陣列 | 陣列必須有相同 Key 的元素才能比較,會逐值比較。 |
陣列 | 任何型別 | 陣列永遠比較大。 |
數字 | 任何型別 | 轉為數字進行比較。 |
1 | var_dump("10" == "1e1"); // bool(true), 轉為數字當作 10 和 10 |
可參考 PHP 教學 - 資料型態 (Data Type) - 上 和 PHP 教學 - 資料型態 (Data Type) - 下 有關轉型的部份。
三元運算子
三元運算子 (Ternary Operator) 是另一種條件運算子,符號為 (?:
),語法如下:
1 | (expr1) ? (expr2) : (expr3) |
當 expr1 成立時,則回傳 expr2;否則回傳 expr3。
1 | // 當 $_POST['action'] 沒有值的時候,$action 給預設值 'default';否則為 $_POST['action'] |
在 PHP 5.3 之後新增用法,能夠省略 expr2:
1 | (expr1) ?: (expr3) |
回傳第一個不為 FALSE 的結果,例如:
1 | // 與上面範例的意義相同 |
類似 JavaScript 的 ||
用法。
錯誤控制運算子
錯誤控制運算子 (Error Control Operator) 使用 (@
) 符號,可以用來忽略錯誤訊息,若 php.ini
的 track_errors
設定為 On
時,隱藏的訊息會存在預定義變數 $php_errormsg
中:
1 | ini_set("error_reporting", E_ALL); |