PHP 運算子 (Operator)

運算子用來對變數和值執行運算。PHP 提供了多種類型的運算子。

算術運算子

用於數學運算:

運算子名稱範例結果
+加法$a + $b兩數相加
-減法$a - $b兩數相減
*乘法$a * $b兩數相乘
/除法$a / $b兩數相除
%取餘數$a % $b除法的餘數
**次方$a ** $ba 的 b 次方
<?php
$a = 10;
$b = 3;

echo $a + $b;   // 13
echo $a - $b;   // 7
echo $a * $b;   // 30
echo $a / $b;   // 3.3333...
echo $a % $b;   // 1
echo $a ** $b;  // 1000

// 負數取餘數
echo -10 % 3;   // -1
echo 10 % -3;   // 1
?>

賦值運算子

用於賦值給變數:

運算子等同於說明
=-賦值
+=$a = $a + $b加法賦值
-=$a = $a - $b減法賦值
*=$a = $a * $b乘法賦值
/=$a = $a / $b除法賦值
%=$a = $a % $b取餘數賦值
**=$a = $a ** $b次方賦值
.=$a = $a . $b字串連接賦值
??=$a = $a ?? $bnull 合併賦值 (PHP 7.4+)
<?php
$a = 10;

$a += 5;  // $a = 15
$a -= 3;  // $a = 12
$a *= 2;  // $a = 24
$a /= 4;  // $a = 6
$a %= 4;  // $a = 2

$str = "Hello";
$str .= " World";  // "Hello World"

// null 合併賦值
$name = null;
$name ??= "Guest";  // $name = "Guest"
?>

比較運算子

用於比較兩個值:

運算子名稱說明
==等於值相等(會自動轉型)
===全等值和型別都相等
!=<>不等於值不相等
!==不全等值或型別不相等
<小於
>大於
<=小於等於
>=大於等於
<=>太空船運算子比較兩值,回傳 -1, 0, 1
<?php
$a = 5;
$b = "5";
$c = 10;

// == vs ===
var_dump($a == $b);   // bool(true) - 值相等
var_dump($a === $b);  // bool(false) - 型別不同

// != vs !==
var_dump($a != $b);   // bool(false)
var_dump($a !== $b);  // bool(true)

// 比較運算
var_dump($a < $c);    // bool(true)
var_dump($a > $c);    // bool(false)
var_dump($a <= 5);    // bool(true)
var_dump($a >= 5);    // bool(true)

// 太空船運算子 (PHP 7+)
echo 1 <=> 2;   // -1 (左邊小於右邊)
echo 2 <=> 2;   // 0 (相等)
echo 3 <=> 2;   // 1 (左邊大於右邊)

// 常用於排序
$numbers = [3, 1, 4, 1, 5];
usort($numbers, fn($a, $b) => $a <=> $b);
print_r($numbers);  // [1, 1, 3, 4, 5]
?>

建議優先使用 ===!== 進行比較,避免自動型別轉換造成的意外:

<?php
var_dump(0 == "hello");   // bool(true) - 意外!"hello" 轉為 0
var_dump(0 === "hello");  // bool(false) - 正確
var_dump(0 == false);     // bool(true)
var_dump(0 === false);    // bool(false)
?>

遞增/遞減運算子

運算子名稱說明
++$a前置遞增先加 1,再回傳
$a++後置遞增先回傳,再加 1
--$a前置遞減先減 1,再回傳
$a--後置遞減先回傳,再減 1
<?php
$a = 5;

echo ++$a;  // 6 (先加後輸出)
echo $a;    // 6

$b = 5;
echo $b++;  // 5 (先輸出後加)
echo $b;    // 6

$c = 5;
echo --$c;  // 4

$d = 5;
echo $d--;  // 5
echo $d;    // 4
?>

邏輯運算子

用於組合條件:

運算子名稱說明
&&and兩者都為 true
||or至少一個為 true
!反轉布林值
xor互斥或恰好一個為 true
<?php
$a = true;
$b = false;

// && (and)
var_dump($a && $b);   // bool(false)
var_dump($a and $b);  // bool(false)

// || (or)
var_dump($a || $b);   // bool(true)
var_dump($a or $b);   // bool(true)

// !
var_dump(!$a);        // bool(false)
var_dump(!$b);        // bool(true)

// xor
var_dump($a xor $b);  // bool(true) - 一個 true 一個 false
var_dump($a xor $a);  // bool(false) - 兩個都 true
?>
&&|| 的優先順序比 andor 高,建議使用 &&||

短路求值

邏輯運算子使用短路求值 (Short-circuit evaluation):

<?php
// && - 如果左邊為 false,不會執行右邊
$result = false && doSomething();  // doSomething() 不會被執行

// || - 如果左邊為 true,不會執行右邊
$result = true || doSomething();  // doSomething() 不會被執行

// 常見用法
$name = $username || "Guest";  // 如果 $username 為假值,使用 "Guest"
?>

字串運算子

運算子說明
.連接字串
.=連接並賦值
<?php
$first = "Hello";
$second = "World";

// 連接
echo $first . " " . $second;  // Hello World

// 連接並賦值
$message = "Hello";
$message .= " World";  // Hello World
?>

陣列運算子

運算子名稱說明
+聯集合併陣列
==相等有相同的鍵值對
===全等有相同的鍵值對,順序和型別也相同
!=<>不相等
!==不全等
<?php
$a = ["a" => "apple", "b" => "banana"];
$b = ["b" => "berry", "c" => "cherry"];

// + 聯集(保留左邊的值)
$c = $a + $b;
print_r($c);
// ["a" => "apple", "b" => "banana", "c" => "cherry"]
// 注意:b 保留了 "banana"

$arr1 = [1, 2, 3];
$arr2 = [1, 2, 3];
$arr3 = ["1", "2", "3"];

var_dump($arr1 == $arr2);   // bool(true)
var_dump($arr1 === $arr2);  // bool(true)
var_dump($arr1 == $arr3);   // bool(true)
var_dump($arr1 === $arr3);  // bool(false) - 型別不同
?>

三元運算子

<?php
$age = 20;

// 三元運算子
$status = ($age >= 18) ? "成年" : "未成年";
echo $status;  // 成年

// 等同於
if ($age >= 18) {
    $status = "成年";
} else {
    $status = "未成年";
}

// 可以巢狀(但不建議,可讀性差)
$grade = 85;
$result = ($grade >= 90) ? "A" : (($grade >= 80) ? "B" : "C");
?>

Null 合併運算子 (??)

PHP 7+ 新增的運算子,用於處理 null 值:

<?php
// ?? - 如果左邊是 null 或未定義,使用右邊的值
$name = $_GET['name'] ?? 'Guest';

// 等同於
$name = isset($_GET['name']) ? $_GET['name'] : 'Guest';

// 可以串連
$name = $_GET['name'] ?? $_POST['name'] ?? 'Guest';

// ??= null 合併賦值 (PHP 7.4+)
$name = null;
$name ??= 'Guest';  // $name = 'Guest'
?>

?? vs ?:

<?php
$a = null;
$b = false;
$c = 0;
$d = '';

// ?? 只檢查 null
echo $a ?? 'default';  // default
echo $b ?? 'default';  // (空,因為 false 不是 null)
echo $c ?? 'default';  // 0
echo $d ?? 'default';  // (空字串)

// ?: 檢查假值
echo $a ?: 'default';  // default
echo $b ?: 'default';  // default
echo $c ?: 'default';  // default
echo $d ?: 'default';  // default
?>

Null 安全運算子 (?->) (PHP 8+)

<?php
class User {
    public ?Address $address = null;
}

class Address {
    public string $city = "Taipei";
}

$user = new User();

// 傳統寫法
$city = $user->address !== null ? $user->address->city : null;

// Null 安全運算子
$city = $user?->address?->city;  // null(不會報錯)

$user->address = new Address();
$city = $user?->address?->city;  // "Taipei"
?>

運算子優先順序

從高到低(部分):

  1. clone new - 複製、建立物件
  2. ** - 次方
  3. ++ -- ~ (type) @ - 遞增遞減、型別轉換
  4. ! - 邏輯非
  5. * / % - 乘除取餘
  6. + - . - 加減連接
  7. << >> - 位元位移
  8. < <= > >= - 比較
  9. == != === !== <> <=> - 相等比較
  10. && - 邏輯且
  11. || - 邏輯或
  12. ?? - null 合併
  13. ? : - 三元
  14. = += -= 等 - 賦值
  15. and - 邏輯且(低優先)
  16. xor - 互斥或
  17. or - 邏輯或(低優先)
<?php
// 使用括號明確優先順序
$result = (2 + 3) * 4;  // 20
$result = 2 + (3 * 4);  // 14
$result = 2 + 3 * 4;    // 14 (乘法優先)

// 常見陷阱
$a = true || false && false;  // true (&&  優先於 ||)
$a = (true || false) && false; // false
?>
當不確定優先順序時,使用括號明確指定運算順序,可以提高程式碼可讀性。