ทั้งสอง Operator ใช้สำหรับ Conditional Assignment แต่มีวัตถุประสงค์และพฤติกรรมต่างกัน
Ternary Operator (?:)
รูปแบบ: (condition) ? expr1 : expr2
// If-Else แบบย่อ
$condition ? $valueIfTrue : $valueIfFalse;
// ตัวอย่าง
$age = 20;
$status = ($age >= 18) ? 'Adult' : 'Minor'; // 'Adult'
// Nested Ternary (ไม่แนะนำ - อ่านยาก)
$grade = ($score >= 90) ? 'A' : (($score >= 80) ? 'B' : 'C');
Null Coalescing Operator (??) - PHP 7.0+
รูปแบบ: (variable) ?? fallback
คืนค่า Variable ถ้า ไม่ใช่ null มิฉะนั้นคืนค่า Fallback
// เทียบเท่า:
isset($var) ? $var : $fallback;
// ตัวอย่าง
$username = $_GET['username'] ?? 'Guest';
// ถ้า $_GET['username'] ไม่ได้ set หรือเป็น null -> 'Guest'
// Chaining (PHP 7+)
$name = $firstName ?? $lastName ?? $nickname ?? 'Anonymous';
ความแตกต่างสำคัญ
| กรณี | Ternary (? :) | Null Coalescing (??) |
|---|---|---|
| Variable ไม่ได้ Set | Notice: Undefined variable | คืนค่า Fallback (ไม่มี Notice) |
| Variable = null | คืนค่า expr2 (false branch) | คืนค่า Fallback |
| Variable = '' (Empty String) | คืนค่า expr2 (false branch) | คืนค่า '' (เพราะไม่ใช่ null) |
| Variable = 0 | คืนค่า expr2 (false branch) | คืนค่า 0 (เพราะไม่ใช่ null) |
| Variable = false | คืนค่า expr2 (false branch) | คืนค่า false (เพราะไม่ใช่ null) |
ตัวอย่างเปรียบเทียบ
$testCases = [
'unset_var' => null, // จำลอง unset
'null_var' => null,
'empty_string' => '',
'zero_int' => 0,
'zero_string' => '0',
'false_bool' => false,
'normal_string' => 'hello',
];
foreach ($testCases as $name => $value) {
// Ternary: ต้อง isset ก่อน ไม่งั้น Notice
$ternary = isset($value) ? $value : 'DEFAULT';
// Null Coalescing: จัดการ unset/null เอง
$coalesce = $value ?? 'DEFAULT';
echo "$name: Ternary='$ternary', Coalesce='$coalesce'\n";
}
/* ผลลัพธ์:
unset_var: Ternary='DEFAULT', Coalesce='DEFAULT'
null_var: Ternary='DEFAULT', Coalesce='DEFAULT'
empty_string: Ternary='DEFAULT', Coalesce=''
zero_int: Ternary='DEFAULT', Coalesce='0'
zero_string: Ternary='DEFAULT', Coalesce='0'
false_bool: Ternary='DEFAULT', Coalesce='false'
normal_string: Ternary='hello', Coalesce='hello'
*/
Elvis Operator (?:) - PHP 5.3+
Short Ternary: $value ?: $fallback (ไม่มี Condition)
คืนค่า $value ถ้า Truthy มิฉะนั้น $fallback
$name = '' ?: 'Guest'; // 'Guest' (Empty String = Falsy)
$name = 'John' ?: 'Guest'; // 'John'
$name = 0 ?: 'Guest'; // 'Guest' (0 = Falsy)
$name = false ?: 'Guest'; // 'Guest'
// vs Null Coalescing
$name = '' ?? 'Guest'; // '' (Empty String ไม่ใช่ null)
$name = 0 ?? 'Guest'; // 0 (Zero ไม่ใช่ null)
สรุป: ใช้ตัวไหนเมื่อไหร่?
- Null Coalescing (
??): ต้องการ Default Value เมื่อ Variable ไม่ได้ Set หรือเป็น null (แนะนำสำหรับ $_GET, $_POST, Config) - Elvis Operator (
?:): ต้องการ Default Value เมื่อ Variable Falsy (false, 0, '', null, []) - เหมือน JavaScript|| - Ternary (
? :): Condition ซับซ้อน ไม่ใช่แค่ Check Null/Falsy
Best Practice แบบรวม
// Config から取得、なければ環境変数、なければ Default
$apiKey = $config['api_key'] ?? $_ENV['API_KEY'] ?? 'default-key';
// Input Validation
$page = (int)($_GET['page'] ?? 1); // Null Coalescing + Cast
$limit = (int)($_GET['limit'] ?: 20); // Elvis (0 -> 20)