PHP教學 - 運算子(Operators) - 上
介紹PHP中運算子的用法,包含種類、優先順序、算術運算子(Arithmetic Operator)、指派運算子(Assignment
Operator)、位元運算子(Bitwise Operator)、比較運算子(Comparison
Operator)、三元運算子(Ternary Operator)和錯誤控制運算子(Error Control Operator)。
1. 簡介
1.1 種類
透過提供一些數值給運算子(Operator,或運算符)進行運算,進而得到一個運算結果,可以想成類似函式的回傳,另外被運算的數值稱為運算元(Operand)。
依據運算元的個數,運算子可以分為三種:
不同的運算子有不同的優先順序(Precedence),例如:1 + 2 * 3是7而不是9,乘號(*)的優先順序大於加號(+)而先做。可以利用括號來增加優先順序,例如:(1 + 2) * 3為9。如果優先順序相同則依據運算子的結合律(Associativity)決定先做左或右邊。以下為運算子由高至低的順序表:
結合律左右的解釋範例如下:
但有時候指派(=)雖然順序較後,但仍然會先進行運算:
2. 算術運算子
算術運算子(Arithmetic Operator)就如同數學的四則運算一般,包含以下運算子:
整數除不盡時會轉為浮點數,以及大整數取餘數時可能會有問題,可以參考PHP教學 - 資料型態(Data Type) - 上 。
3. 指派運算子
基本的指派運算子(Assignment Operator)符號是(=),你可能會把它想成數學的等於,但實際上不能這樣想,正確的意思是:將右邊的結果放入左邊。
陣列的宣告時使用(=>)的符號來指派陣列元素的內容。除此之外,指派運算子可以和二元運算子結合使用,用法如下:
$a X= $b 相當於$a = $a X $b,X代換為任意二元運算子,例如:$a += $b相當於$a = $a + $b。
4. 位元運算子
位元運算子(Bitwise Operator)能夠對整數的位元進行運算,包含以下運算子:
向左位移時,正負號不會保留;而向右位移時,正負號會保留。進行位元運算時,如果不是整數型別會先轉成整數型別處理,但當兩邊都是字串型別時,會以字元的ASCII碼來進行處理(位移運算除外)。
位移運算的位移量會取平台位元數的餘數進行運算,例如在32位元平台的$a << 33會轉為$a << (33 % 32)相當於$a << 1,一些範例如下:
5. 比較運算子
比較運算子(Comparison Operator)可以比較兩個值,並將結果以布林回傳,包含以下運算子:
如果字串和數字比較或兩個字串皆為數字的形式比較時,字串會先轉為數字後比較,例如:
各種型別進行比較時,會根據以下的規則來做處理,情況重疊時以較上方的規則為準:
可參考PHP 教學 - 型別有關轉型的部份。
6. 三元運算子
三元運算子(Ternary Operator)是另一種條件運算子,符號為(?:),語法如下:
在PHP5.3之後新增用法,能夠省略expr2:
類似JavaScript的||用法。
7. 錯誤控制運算子
錯誤控制運算子(Error Control Operator)使用(@)符號,可以用來忽略錯誤訊息,若php.ini的track_errors設定為On時,隱藏的訊息會存在預定義變數$php_errormsg中:
1. 簡介
1.1 種類
透過提供一些數值給運算子(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
2
3
4
5
6
7
8
9
10
| <?php// 結合律: 左var_dump(7 * 3 / 3); // int(7), => 21 / 3var_dump(7 / 3 * 3); // float(7), => 2.3333.. * 3 先轉為float// 結合律: 右$a = 1;$b = 2;$a = $b += 3; // $b = 5, $a = 5?> |
1
2
3
4
5
| <?php$a = false;$b = true;var_dump(!$a = $b); // bool(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相同) |
3. 指派運算子
基本的指派運算子(Assignment Operator)符號是(=),你可能會把它想成數學的等於,但實際上不能這樣想,正確的意思是:將右邊的結果放入左邊。
陣列的宣告時使用(=>)的符號來指派陣列元素的內容。除此之外,指派運算子可以和二元運算子結合使用,用法如下:
$a X= $b 相當於$a = $a X $b,X代換為任意二元運算子,例如:$a += $b相當於$a = $a + $b。
1
2
3
4
5
6
7
8
| <?php$num = 3;$num *= 5; // $num: 15$teletubbies = array('dindin'=>'紫色', 'lala'=>'黃色');$fool = "Lala是";$fool .= $teletubbies['lala']; // $fool: Lala是黃色?> |
位元運算子(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次方之整數) |
位移運算的位移量會取平台位元數的餘數進行運算,例如在32位元平台的$a << 33會轉為$a << (33 % 32)相當於$a << 1,一些範例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| <?php// 只顯示最右邊8個bitfunction toBits($num, $bits = 8) { return substr(sprintf("%0{$bits}b", $num), -$bits);}$a = 55;$b = 66;echo toBits($a) . "\n"; // 00110111echo toBits($b) . "\n"; // & 01000010 //-----------echo toBits($a & $b) . "\n"; // 00000010 : 2 // 00110111 // | 01000010 //-----------echo toBits($a | $b) . "\n"; // 01110111 : 119 // 00110111 // ^ 01000010 //-----------echo toBits($a ^ $b) . "\n"; // 01110101 : 117 // ~ 00110111 //------------echo toBits(~$a) . "\n"; // 11001000 : -56 // 00110111 << 2 //------------echo toBits($a << 2) . "\n"; // 11011100 : 220 // 00110111 >> 33 //------------echo toBits($a >> 33) . "\n"; // 00011011 : 27?> |
比較運算子(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <?phpvar_dump(0 == "a"); // bool(true), 轉為數字當作 0 和 0var_dump(0 === "a"); // bool(false) 型別不同var_dump("1" != "01"); // bool(false), 轉為數字當作 1 和 1var_dump("10" <> "1e1"); // bool(false), 轉為數字當作 10 和 10var_dump(100 != "1e2"); // bool(false), 轉為數字當作 100 和 100var_dump(100 !== "1e2"); // bool(true), 型別不同switch ("a") {case 0: echo "會進來"; // 轉為數字0 break;case "a": echo "不會進來"; // 已經進入case 0, 永遠不會進入此處 break;}?> |
| 型別1 | 型別2 | 結果 |
|---|---|---|
| 數字形式字串 | 數字形式字串 | 轉為數字進行比較 。 |
| 字串 | 字串 | 以字串內容進行比較 。 |
| 字串 | NULL | NULL轉為空字串""進行比較 。 |
| 布林 | 任何型別 | 轉為布林進行比較,且FALSE < TRUE。 |
| 物件 | 物件 | 不同類別無法比較,相同類別在PHP4比較方式和陣列一樣,在PHP5中更為複雜,在之後的章節再做討論。 |
| 實作toString物件 | 任何型別 | 以toString()結果字串進行比較,與字串比較規則相同。 |
| 物件 | 字串 | 物件永遠比較大。 |
| 陣列 | 陣列 | 陣列必須有相同Key的元素才能比較,會逐值比較。 |
| 陣列 | 任何型別 | 陣列永遠比較大。 |
| 數字 | 任何型別 | 轉為數字進行比較。 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| <?phpvar_dump("10" == "1e1"); // bool(true), 轉為數字當作 10 和 10var_dump("b" > "a"); // bool(true)var_dump("" == NULL); // bool(true)var_dump(FALSE == NULL); // bool(true)var_dump(2 > TRUE); // bool(false), 轉為布林 TRUE > TRUEclass A { function __toString() { return "A"; }}$a = new A;$s = new stdClass;// $a 和 $s 無法比較var_dump($a == $s); // bool(false)var_dump($a > $s); // bool(false)var_dump($a < $s); // bool(false)var_dump($a != $s); // bool(true)var_dump($a == "A"); // bool(true), 轉為字串 "A" == "A"var_dump($s > "9527"); // bool(true), 物件永遠較大var_dump(array("fool" => 55) < array("fool" => 66)); // bool(true)var_dump(array() > 9527); // bool(true), 陣列永遠較大var_dump(55 < "66"); // bool(true), 轉為數字比較?> |
6. 三元運算子
三元運算子(Ternary Operator)是另一種條件運算子,符號為(?:),語法如下:
(expr1) ? (expr2) : (expr3)當expr1成立時,則回傳expr2;否則回傳expr3。
1
2
3
4
| <?php// 當$_POST['action']沒有值的時候,$action給預設值'default';否則為$_POST['action']$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];?> |
(expr1) ?: (expr3)回傳第一個不為FALSE的結果,例如:
1
2
3
4
5
6
7
8
9
10
11
| <?php// 與上面範例的意義相同$action = $_GET['action'] ?: 'default';$a = "";$b = "0";$d = "first";$e = "second";$str = $a ?: $b ?: $c ?: $d ?: $e;echo $str; // first, 取得第一個轉為布林不為FALSE的值?> |
7. 錯誤控制運算子
錯誤控制運算子(Error Control Operator)使用(@)符號,可以用來忽略錯誤訊息,若php.ini的track_errors設定為On時,隱藏的訊息會存在預定義變數$php_errormsg中:
1
2
3
4
5
6
7
| <?phpini_set("error_reporting", E_ALL);$f = file("nofile"); // Warning: file(nofile): failed to open stream: No such file or directory in K:\mowes\www\learn\php\test.php on line 3$f = @file("nofile"); // 不會顯示// php.ini的track_errors有開啟時, 隱藏的訊息會存在 $php_errormsgecho $php_errormsg; // file(nofile): failed to open stream: No such file or directory?> |
留言
張貼留言