3-3: Ternary & Null Coalescing
Objectives
- Menggunakan ternary operator
- Mengenal null coalescing operator
- Kapan menggunakan masing-masing
- Memahami shorthand ternary (Elvis operator)
- Mengenal null coalescing assignment (
??=) dan nullsafe operator (?->)
Menulis Kondisi Secara Ringkas
Pola yang paling sering muncul di kode nyata adalah: cek sebuah kondisi, lalu simpan salah satu dari dua nilai. Dengan if-else biasa, pola ini butuh 5-6 baris:
<?php
$age = 20;
if ($age >= 18) {
$status = "Dewasa";
} else {
$status = "Anak-anak";
}
echo $status; // Dewasa
?>
Untuk kasus sesederhana ini, PHP menyediakan operator yang bisa memadatkannya menjadi satu baris. Di materi ini kita akan mengenal tiga operator: ternary (?:), Elvis (?: tanpa kondisi), dan null coalescing (??).
| Cara | Panjang Kode | Kejelasan | Kegunaan |
|---|---|---|---|
if-else | 5-6 baris | Jelas tapi panjang | Semua kasus |
Ternary ?: | 1 baris | Ringkas | Kondisi true/false sederhana |
Null coalescing ?? | 1 baris | Ringkas | Khusus cek null/undefined |
Ternary Operator
<?php
// Basic ternary
$age = 20;
$status = ($age >= 18) ? "Dewasa" : "Anak-anak";
echo $status; // Dewasa
?>
Struktur ternary: kondisi ? nilai_jika_true : nilai_jika_false.
| Bagian | Contoh | Arti |
|---|---|---|
| Kondisi | ($age >= 18) | Ekspresi yang dievaluasi |
? | ? | Pemisah: "kalau true..." |
| Nilai true | "Dewasa" | Dikembalikan jika kondisi true |
: | : | Pemisah: "...kalau false" |
| Nilai false | "Anak-anak" | Dikembalikan jika kondisi false |
Ternary adalah expression, bukan statement — artinya hasilnya bisa langsung disimpan ke variabel, dikirim ke function, atau di-echo. Inilah keunggulan utamanya dibanding if-else.
<?php
$jam = 9;
// Bisa langsung dipakai di dalam string
echo "Selamat " . ($jam < 12 ? "pagi" : "sore") . "!"; // Selamat pagi!
// Bisa jadi argumen function
function sapa(string $waktu): string
{
return "Halo, $waktu";
}
echo sapa($jam < 12 ? "pagi" : "sore"); // Halo, pagi
?>
Nested Ternary (hati-hati!)
Ternary bisa bersarang, tapi readability-nya turun drastis:
<?php
$nilai = 85;
// ⚠️ Bekerja, tapi sulit dibaca
$grade = $nilai >= 90 ? "A" : ($nilai >= 80 ? "B" : ($nilai >= 70 ? "C" : "D"));
echo $grade; // B
// ✅ Lebih jelas dengan if-elseif untuk banyak cabang
if ($nilai >= 90) {
$grade = "A";
} elseif ($nilai >= 80) {
$grade = "B";
} elseif ($nilai >= 70) {
$grade = "C";
} else {
$grade = "D";
}
echo $grade; // B
?>
Jangan menumpuk ternary lebih dari satu level. PHP 8 bahkan membuat nested ternary tanpa kurung menjadi error fatal (Unparenthesized a ? b : c ? d : e is not supported). Selalu beri kurung jika terpaksa, atau pindah ke if-elseif / match.
Shorthand Ternary / Elvis Operator (?:)
PHP menyediakan versi pendek ternary: $a ?: $b artinya "kembalikan $a jika truthy, selain itu $b". Operator ini dijuluki Elvis operator karena bentuknya mirip rambut Elvis:
?: ──-> ╮
╯ (rambut Elvis Presley)
<?php
// Shorthand ternary (PHP 7.4+)
$name = "";
$display = $name ?: "Guest";
echo $display; // Guest
// Sama dengan:
$display = $name ? $name : "Guest";
// Berbeda dengan ?? — cek truthiness, bukan hanya null!
$nilai = 0;
echo $nilai ?: "default"; // default (0 itu falsy)
echo $nilai ?? "default"; // 0 (0 bukan null)
?>
Gunakan ?: saat kriteria "layak pakai" adalah truthy — misalnya string tidak kosong. Gunakan ?? saat kriteria hanya ada nilainya (tidak null) — misalnya konfigurasi yang bisa berupa string kosong yang valid.
Null Coalescing Operator (??)
<?php
// ?? returns first non-null value
$a = null;
$b = "default";
$result = $a ?? $b;
echo $result; // default
// Chaining
$var1 = null;
$var2 = null;
$var3 = "terakhir";
$result = $var1 ?? $var2 ?? $var3 ?? "default";
echo $result; // terakhir
?>
Keunggulan terbesar ??: ia tidak melempar warning saat variabel atau key array tidak ada. Bandingkan:
<?php
// Tanpa ??: warning "Undefined array key" (PHP 8)
// $warna = $_GET["warna"]; // ❌ Warning!
// Dengan ??: aman, langsung pakai default
$warna = $_GET["warna"] ?? "biru";
echo $warna; // biru (jika tidak ada parameter warna)
// Juga bekerja untuk array dan property
$user = ["nama" => "Andi", "email" => null];
echo $user["nama"] ?? "Anonim"; // Andi
echo $user["email"] ?? "no-reply"; // no-reply (null)
echo $user["umur"] ?? "?"; // ? (key tidak ada, tidak error)
?>
?? adalah cara paling aman dan idiomatis untuk membaca input user ($_GET, $_POST) atau konfigurasi opsional. Ia menangani tiga kasus sekaligus: variabel tidak ada, key tidak ada, dan nilai null.
Null Coalescing Assignment (??=)
PHP 7.4+ menyediakan operator ??= yang mengisi variabel hanya jika saat ini null:
<?php
$cache = null;
// Jika $cache null, isi dengan hasil function
$cache ??= hitung_biaya();
echo $cache;
function hitung_biaya(): int
{
return 15000;
}
// Output: 15000
// Sama dengan:
// if ($cache === null) { $cache = hitung_biaya(); }
// Kedua kalinya, function TIDAK dipanggil lagi:
$cache ??= hitung_biaya();
echo $cache; // 15000 (tetap, tidak dihitung ulang)
?>
Pola ini sangat berguna untuk memoization — menyimpan hasil perhitungan agar tidak dihitung berulang.
Nullsafe Operator (?->) — PHP 8.0+
Saat bekerja dengan object yang mungkin null, rantai pemanggilan biasa akan error. Nullsafe operator menghentikan rantai dan mengembalikan null jika ada satu link yang null:
<?php
class User
{
public ?Profil $profil = null;
}
class Profil
{
public string $kota = "Jakarta";
}
$user = new User();
// Tanpa nullsafe: fatal error "Call to a member function on null"
// $kota = $user->profil->kota; // ❌
// Dengan nullsafe: aman, hasil null
$kota = $user->profil?->kota;
echo $kota ?? "Lokasi tidak diketahui"; // Lokasi tidak diketahui
// Kombinasi dengan ??
$user2 = new User();
$user2->profil = new Profil();
echo $user2->profil?->kota ?? "Lokasi tidak diketahui"; // Jakarta
?>
Ternary vs Null Coalescing
| Operator | Cek | Use Case |
|---|---|---|
?: (ternary) | Truthiness | Boolean expression |
?: (elvis) | Truthiness | Nilai default jika falsy |
?? | NULL/undefined | Default value |
<?php
$value = "";
// Ternary - empty string is falsy
$result = $value ? $value : "default";
echo $result; // default
// Null coalescing - empty string is NOT null
$result = $value ?? "default";
echo $result; // "" (empty string)
?>
Perbedaan ini sangat penting ketika nilai yang valid justru berupa nilai "falsy":
Nilai $x | $x ?: "d" | $x ?? "d" |
|---|---|---|
"teks" | "teks" | "teks" |
"" | "d" | "" |
0 | "d" | 0 |
null | "d" | "d" |
| (tidak ada) | warning | "d" |
Common Mistakes
Mistake 1: Mengira ?? dan ?: sama
<?php
$qty = 0; // user belum pilih jumlah
// ❌ Salah kalau 0 itu nilai yang sah (misal "gratis ongkir")
$pesan = $qty ?: "pilih jumlah dulu";
echo $pesan; // "pilih jumlah dulu" — padahal 0 valid!
// ✅ Pakai ?? jika 0 adalah nilai yang sah
$pesan = $qty ?? "pilih jumlah dulu";
echo $pesan; // 0
?>
Mistake 2: Nested ternary tanpa kurung (PHP 8 fatal)
<?php
// ❌ PHP 8: Fatal error — unparenthesized nested ternary
// $hasil = $a ? 1 : $b ? 2 : 3;
// ✅ Selalu kurung saat nested
$a = false;
$b = true;
$hasil = $a ? 1 : ($b ? 2 : 3);
echo $hasil; // 2
?>
Mistake 3: Menggunakan ?? untuk memeriksa kesalahan logika
<?php
$harga = 0; // harga gratis — nilai valid
// ❌ Salah: ini menutupi bug! Harga 0 seharusnya tetap 0
// $harga_final = $harga ?? 10000;
// ✅ Benar: gunakan ?? hanya untuk nilai yang mungkin null/tidak ada
$harga_final = $harga ?? 10000;
echo $harga_final; // 0 — benar, karena 0 bukan null
?>
?? bukan pengganti validasi bisnis. Ia hanya menangani ketiadaan nilai, bukan nilai yang salah.
Pro Tips
??adalah default choice untuk membaca input user, array, dan config — aman dari warning.- Gunakan
?:hanya jika kamu memang ingin memfilter nilai falsy (string kosong,0,false). - Jangan nested ternary — jika butuh 3+ cabang, gunakan
match(PHP 8) atauif-elseif. - Kombinasikan
?->dan??untuk rantai object opsional:$user?->alamat?->kota ?? "Tidak ada". ??=sangat cocok untuk caching/memoization — hitung sekali, pakai terus.- Selalu baca ternary dari kiri:
kondisi ? A : B— jika sudah tidak terbaca, refactor.
Exercise
- Gunakan ternary untuk cek apakah user logged in
- Gunakan null coalescing untuk get user preference dengan default
- Apa output dari:
<?php
echo null ?? "" ?? "fallback";
?>
- Tulis satu baris kode untuk membaca
$_GET["page"]dengan default"home"tanpa warning. - Refactor kode berikut agar lebih ringkas dengan
??dan??=:
<?php
$biaya = null;
if ($biaya === null) {
$biaya = 5000;
}
$diskon = isset($_POST["diskon"]) ? $_POST["diskon"] : 0;
?>
- Apa perbedaan output
$nilai ?: "d"vs$nilai ?? "d"jika$nilai = "0"? (Jawab:?:memberi"d"karena"0"falsy,??memberi"0"karena bukan null — cek denganvar_dump!)
Summary
| Operator | Bentuk | Cek | Hasil jika gagal |
|---|---|---|---|
| Ternary | $c ? $a : $b | Truthiness $c | $b |
| Elvis | $a ?: $b | Truthiness $a | $b |
| Null coalescing | $a ?? $b | $a null/tidak ada | $b |
| Coalesce assign | $x ??= $v | $x null? | isi $x dengan $v |
| Nullsafe | $a?->b | $a null? | null (tanpa error) |
Klik tombol ini setelah menyelesaikan materi
Quiz Bab 3
Uji pemahamanmu tentang Struktur Kontrol