PHP 三元運算子(Ternary Operator)是條件判斷的簡潔寫法,但不同寫法在可讀性、效能、副作用上存在細微差異。本文詳細對比三種常見模式,並給出專案編碼規範建議。
<?php
$a = 2;
($a == 1) ? $test = "企業" : $test = "地區";
echo $test; // 地區
缺點:
<?php
$a = 2;
$test = ($a == 1) ? "企業" : "地區";
echo $test; // 地區
優點:
<?php
$a = 2;
if ($a == 1) {
$test = "企業";
} else {
$test = "地區";
}
echo $test;
適用場景:
<?php
$score = 85;
$grade = $score >= 90 ? 'A' : ($score >= 80 ? 'B' : ($score >= 60 ? 'C' : 'F'));
// 建議改用 match (PHP 8.0+)
$grade = match (true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 60 => 'C',
default => 'F',
};
<?php
// 簡寫:$a ?: $b 等同於 $a ? $a : $b
$username = $_GET['name'] ?: '訪客'; // 空字串、null、false 都會用預設值
// 與 null 聯合運算子 ?? 差異 (PHP 7.0+)
$input = '';
echo $input ?: '預設'; // 輸出「預設」(空字串為 false)
echo $input ?? '預設'; // 輸出空字串(null 才用預設)
<?php
// 錯誤:echo 會先執行,導致三元運算子判斷 echo 的回傳值 (1)
echo '結果: ' . $a > 0 ? '正數' : '負數';
// 正確:加括號明確分組
echo '結果: ' . ($a > 0 ? '正數' : '負數');
| 寫法 | Opcode 數量 | 執行速度 | 記憶體 |
|---|---|---|---|
| 三元運算子 (寫法二) | 較少 | 略快 | 相同 |
| if-else | 略多 | 略慢 | 相同 |
實際專案中差異可忽略不計,可讀性優於微觀效能。
$var = $cond ? 'A' : 'B';?? (null 聯合) 處理預設值,?: (Elvis) 處理 falsy 值match 表達式<?php
// ❌ 原始碼:難以閱讀的巢狀三元
$status = $user->is_active ? ($user->is_vip ? 'VIP啟用' : '普通啟用') : ($user->is_vip ? 'VIP停用' : '普通停用');
// ✅ 重構:使用 match (PHP 8.0+)
$status = match([$user->is_active, $user->is_vip]) {
[true, true] => 'VIP啟用',
[true, false] => '普通啟用',
[false, true] => 'VIP停用',
default => '普通停用',
};
// ✅ 或提取方法增加語意
private function getUserStatus(User $user): string {
if (!$user->is_active) return $user->is_vip ? 'VIP停用' : '普通停用';
return $user->is_vip ? 'VIP啟用' : '普通啟用';
}
總結:三元運算子是「表達式」,核心價值在於回傳值而非執行動作。掌握 ?:、??、match 的語意差異,能寫出更簡潔、無 Bug 的條件邏輯。