萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 三元運算子 (?:) 完整指南:語法、巢狀用法、適用場景與可讀性權衡

語法定義

(條件運算式) ? 真值運算式 : 假值運算式

相當於 if-else 的單行簡寫,有回傳值 (可直接賦值給變數)。

基本範例

<?php
$a = 10; $b = 20;
// 若 $a > $b 則 $a-$b,否則 $a+$b
$c = ($a > $b) ? ($a - $b) : ($a + $b);
echo $c; // 30

// 簡化變數賦值
$status = $isActive ? '啟用' : '停用';
$label = $count > 0 ? "{$count} 項" : '無資料';
?>

進階用法

多重運算式 (配合逗號運算子或串聯)

<?php
// PHP 不支援逗號運算子在表達式中執行多句
// 錯誤寫法:($cond) ? (doA(), doB()) : (doC(), doD());

// 正確:用函數封裝或分開寫
$result = $cond ? (funcA(), funcB()) : (funcC(), funcD()); // 僅回傳最後一個值

// 推薦:複雜邏輯用 if-else
if ($cond) { funcA(); funcB(); } else { funcC(); funcD(); }
?>

巢狀三元運算子 (需加括號明確優先序)

<?php
$score = 85;
$grade = ($score >= 90) ? 'A' :
         (($score >= 80) ? 'B' :
         (($score >= 70) ? 'C' : 'D'));
echo $grade; // B

// 等同於
if ($score >= 90) $grade = 'A';
elseif ($score >= 80) $grade = 'B';
elseif ($score >= 70) $grade = 'C';
else $grade = 'D';
?>

鏈式比較 (PHP 8.0+ match 更適合)

<?php
// 三元運算子模擬多重分支
$role = 'admin';
$permission = ($role === 'admin') ? 'full' :
              (($role === 'editor') ? 'write' :
              (($role === 'viewer') ? 'read' : 'none'));

// PHP 8.0+ match 運算式 (更清晰、嚴格比較、無型別轉換)
$permission = match($role) {
    'admin' => 'full',
    'editor' => 'write',
    'viewer' => 'read',
    default => 'none',
};
?>

實務應用場景

場景範例
預設值賦值$page = $_GET['page'] ?? 1; (PHP 7+ null 合併更好)
條件式輸出echo $user->isAdmin ? '管理員' : '一般會員';
三元運算子回傳值給函數func($cond ? $val1 : $val2);
模板引擎輸出<?= $show ? '<div>內容</div>' : '' ?>

可讀性陷阱與避坑指南

  1. 避免超過 1 層巢狀:超過請改用 if-elseif 或 match。
  2. 括號明確分組:($a > $b) ? $x : $y 而非 $a > $b ? $x : $y (雖然優先序正確,但加括號更易讀)。
  3. 勿用於複雜副作用邏輯:三元運算子為運算式,非陳述式,不適合包含多行邏輯、副作用操作。
  4. null 合併運算子 (??) 優先:$var = $input ?? 'default'; 比 $var = isset($input) ? $input : 'default'; 更簡潔且語意精確 (只判斷 null)。

結語

三元運算子是「簡單條件賦值/輸出」的利器,能讓代碼更緊湊。但可讀性永遠優先:超過一行、巢狀超過一層、包含副作用時,請毫不猶豫改寫為 if-elseif-else 或 PHP 8 match。善用 ?? (null 合併) 和 ?: (Elvis operator: $x ?: 'default' 等同 $x ? $x : 'default') 處理預設值,是現代 PHP 風格標誌。

copyright © 萬盛學電腦網 all rights reserved