BAB 3: STRUKTUR KONTROL

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
<?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 (??).

CaraPanjang KodeKejelasanKegunaan
if-else5-6 barisJelas tapi panjangSemua kasus
Ternary ?:1 barisRingkasKondisi true/false sederhana
Null coalescing ??1 barisRingkasKhusus cek null/undefined

Ternary Operator

php
<?php

// Basic ternary
$age = 20;
$status = ($age >= 18) ? "Dewasa" : "Anak-anak";

echo $status;  // Dewasa

?>

Struktur ternary: kondisi ? nilai_jika_true : nilai_jika_false.

BagianContohArti
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
💡Tip

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
<?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
<?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

?>
⚠️Perhatian

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
<?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)

?>
💡Tip

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
<?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
<?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)

?>
💡Tip

?? 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
<?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
<?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

OperatorCekUse Case
?: (ternary)TruthinessBoolean expression
?: (elvis)TruthinessNilai default jika falsy
??NULL/undefinedDefault value
php
<?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
<?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

// ❌ 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
<?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

  1. ?? adalah default choice untuk membaca input user, array, dan config — aman dari warning.
  2. Gunakan ?: hanya jika kamu memang ingin memfilter nilai falsy (string kosong, 0, false).
  3. Jangan nested ternary — jika butuh 3+ cabang, gunakan match (PHP 8) atau if-elseif.
  4. Kombinasikan ?-> dan ?? untuk rantai object opsional: $user?->alamat?->kota ?? "Tidak ada".
  5. ??= sangat cocok untuk caching/memoization — hitung sekali, pakai terus.
  6. Selalu baca ternary dari kiri: kondisi ? A : B — jika sudah tidak terbaca, refactor.

Exercise

  1. Gunakan ternary untuk cek apakah user logged in
  2. Gunakan null coalescing untuk get user preference dengan default
  3. Apa output dari:
php
<?php
echo null ?? "" ?? "fallback";
?>
  1. Tulis satu baris kode untuk membaca $_GET["page"] dengan default "home" tanpa warning.
  2. Refactor kode berikut agar lebih ringkas dengan ?? dan ??=:
php
<?php
$biaya = null;
if ($biaya === null) {
    $biaya = 5000;
}
$diskon = isset($_POST["diskon"]) ? $_POST["diskon"] : 0;
?>
  1. Apa perbedaan output $nilai ?: "d" vs $nilai ?? "d" jika $nilai = "0"? (Jawab: ?: memberi "d" karena "0" falsy, ?? memberi "0" karena bukan null — cek dengan var_dump!)

Summary

OperatorBentukCekHasil jika gagal
Ternary$c ? $a : $bTruthiness $c$b
Elvis$a ?: $bTruthiness $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