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 種類
透過提供一些數值給運算子(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 / 3 var_dump(7 / 3 * 3); // float(7), => 2.3333.. * 3 先轉為float // 結合律: 右 $a = 1; $b = 2; $a = $b += 3; // $b = 5, $a = 5 ?> |
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。
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,一些範例如下:
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個bit function toBits( $num , $bits = 8) { return substr (sprintf( "%0{$bits}b" , $num ), - $bits ); } $a = 55; $b = 66; echo toBits( $a ) . "\n" ; // 00110111 echo 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 |
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| <?php var_dump(0 == "a" ); // bool(true), 轉為數字當作 0 和 0 var_dump(0 === "a" ); // bool(false) 型別不同 var_dump( "1" != "01" ); // bool(false), 轉為數字當作 1 和 1 var_dump( "10" <> "1e1" ); // bool(false), 轉為數字當作 10 和 10 var_dump(100 != "1e2" ); // bool(false), 轉為數字當作 100 和 100 var_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
| <?php var_dump( "10" == "1e1" ); // bool(true), 轉為數字當作 10 和 10 var_dump( "b" > "a" ); // bool(true) var_dump( "" == NULL); // bool(true) var_dump(FALSE == NULL); // bool(true) var_dump(2 > TRUE); // bool(false), 轉為布林 TRUE > TRUE class 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。
2
3
4
| <?php // 當$_POST['action']沒有值的時候,$action給預設值'default';否則為$_POST['action'] $action = ( empty ( $_POST [ 'action' ])) ? 'default' : $_POST [ 'action' ]; ?> |
(expr1) ?: (expr3)回傳第一個不為FALSE的結果,例如:
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中:
<?php ini_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_errormsg echo $php_errormsg; // file(nofile): failed to open stream: No such file or directory ?>
留言
張貼留言