Banyak keputusan dalam program sederhana sekali: jika kondisi benar pakai nilai A, jika salah pakai nilai B. Menulis struktur if/else untuk keputusan sekecil itu terasa berlebihan, apalagi ketika hasilnya hanya untuk diisi ke sebuah variabel. Ternary operator (? :) memindahkan pilihan tersebut ke dalam satu ekspresi: $status = $usia >= 17 ? "dewasa" : "anak". Pada Chapter ini kita akan mempelajari bentuk lengkap ternary, bentuk pendeknya ?:, perbedaannya dengan ??, aturan wajib tanda kurung saat menyusun bertingkat, serta kapan sebaiknya kita mundur ke if atau match.
Memilih Nilai dengan Ternary #
Bentuk lengkapnya adalah kondisi ? nilaiJikaBenar : nilaiJikaSalah. PHP mengevaluasi kondisi tepat satu kali, lalu mengambil salah satu dari dua nilai — nilai yang tidak terpilih tidak pernah dievaluasi:
<?php
$usia = 20;
$status = $usia >= 17 ? "dewasa" : "anak-anak";
echo "Status: $status\n";
$nilaiUjian = 78;
$hasilUjian = $nilaiUjian >= 75 ? "lulus" : "mengulang";
echo "Hasil ujian: $hasilUjian\n";Output yang Dihasilkan:
Status: dewasa
Hasil ujian: lulusPada baris ketiga, perbandingan $usia >= 17 bernilai true sehingga ekspresi menghasilkan "dewasa"; string "anak-anak" di sebelah kanan tanda titik dua diabaikan. Baris keenam memperlihatkan pola yang sama dengan ambang batas berbeda. Ternary adalah ekspresi — menghasilkan nilai — dan itulah perbedaan fundamentalnya dari if yang merupakan statement (struktur kontrol yang dibahas tuntas pada Section Control Flow).
Bentuk Pendek Ternary #
Saat nilai kondisi dan nilai hasil benarnya sama persis, kita bisa memangkasnya menjadi nilai ?: nilaiCadangan. Bentuk pendek ini mengevaluasi nilai sekali: jika dianggap benar (truthy) hasilnya nilai itu sendiri; jika dianggap salah (falsy) hasilnya nilaiCadangan:
<?php
$namaTampilan = "Budi Santoso";
$namaPanggilan = "";
$stok = 0;
echo ($namaTampilan ?: "Tamu") . "\n";
echo ($namaPanggilan ?: "Tamu") . "\n";
echo ($stok ?: "habis") . "\n";Output yang Dihasilkan:
Budi Santoso
Tamu
habisMari kita telaah ketiga barisnya:
- Baris 6:
"Budi Santoso"adalah string tidak kosong sehingga truthy — nilai itu sendiri yang dipakai. - Baris 7:
""adalah string kosong sehingga falsy — nilai cadangan"Tamu"yang dipakai. - Baris 8:
0juga falsy, sehingga label"habis"yang tercetak.
Kriteria truthy/falsy menjadi tulang punggung bentuk pendek ini — daftar lengkap nilai falsy dibahas pada Chapter Truthiness dan Short-Circuit
. Karena hanya ada satu operand kondisi, ?: paling cocok untuk pola “pakai nilai ini, kecuali kosong”.
Perbedaan ?: dan ?? #
Bab ini sering menimbulkan kebingungan, jadi mari kita adu keduanya dalam satu program. Operator ?: mengganti semua nilai falsy; operator ?? hanya mengganti null (atau nilai yang tidak ada):
<?php
$diskon = 0;
$kodeKupon = "0";
echo ($diskon ?? 10) . "\n";
echo ($diskon ?: 10) . "\n";
echo ($kodeKupon ?? "tanpa kupon") . "\n";
echo ($kodeKupon ?: "tanpa kupon") . "\n";Output yang Dihasilkan:
0
10
0
tanpa kuponNilai 0 lolos dari ?? (bukan null) tetapi diganti oleh ?: (falsy). Hal yang sama terjadi pada string "0" — satu-satunya string falsy di PHP. Aturan praktisnya: gunakan ?? untuk data yang mungkin tidak ada (parameter request, kunci konfigurasi), dan ?: untuk data yang mungkin kosong (input pengguna yang belum diisi).
Perbedaan kedua lebih tajam lagi: ?: membaca nilai kondisinya, sehingga variabel yang belum pernah didefinisikan memicu peringatan:
<?php
$tema = $preferensiPengguna ?? "terang";
echo "Tema: $tema\n";Output yang Dihasilkan:
Tema: terangBlok di atas aman karena ?? memeriksa keberadaan sebelum membaca. Bandingkan dengan ?: pada variabel yang sama:
<?php
$tema = $preferensiPengguna ?: "terang";
echo "Tema: $tema\n";Variabel $preferensiPengguna belum pernah didefinisikan, dan kali ini PHP benar-benar membacanya — hasilnya peringatan sebelum nilai cadangan terpakai:
Warning: Undefined variable $preferensiPengguna in contoh.php on line 2
Tema: terangPesan di atas diambil dari eksekusi nyata di PHP 8; nama berkas dan nomor baris menyesuaikan kode Anda. Kesimpulannya: untuk data yang mungkin belum ada, ?? selalu menjadi pilihan yang aman. (Kedua operator ini juga dibandingkan pada Chapter Null Coalescing Operator
dari sisi kebalikannya.)
Ternary Bertingkat Wajib Memakai Kurung #
Ternary boleh disusun bertingkat — nilai hasilnya pun bisa berupa ternary lain. Syaratnya satu dan tidak bisa ditawar: setiap ternary tingkat dalam harus dibungkus tanda kurung:
<?php
$nilai = 85;
$predikat = $nilai >= 90 ? "A" : ($nilai >= 80 ? "B" : ($nilai >= 70 ? "C" : "D"));
echo "Predikat: $predikat\n";Output yang Dihasilkan:
Predikat: BKarena $nilai tidak mencapai 90 tetapi melampaui 80, ekspresi di dalam kurung terluar menghasilkan "B". Tanda kurung di sini bukan hiasan; mari kita lihat apa yang terjadi tanpanya:
<?php
$nilai = 85;
$predikat = $nilai >= 90 ? "A" : $nilai >= 80 ? "B" : $nilai >= 70 ? "C" : "D";Kode tanpa kurung tersebut tidak pernah sampai dieksekusi — PHP langsung menolaknya saat membaca berkas:
Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in contoh.php on line 4Aturan ini diberlakukan sejak PHP 8.0. Pada PHP 7, ekspresi tanpa kurung justru dievaluasi dari kiri ((a ? b : c) ? d : e) — perilaku yang terbukti melahirkan bug susah dilacak karena jarang sesuai maksud penulisnya. PHP 8 memilih berhenti total dan memaksa kita menulis maksud secara eksplisit, yang sejalan dengan prinsip umum: bila ternary bertingkat mulai terasa sesak, itu pertanda struktur lain lebih layak dipakai.
Kapan Sebaiknya Tidak Memakai Ternary #
Ternary paling sehat saat satu barisnya masih bisa dibaca dalam satu tarikan napas: kondisi sederhana, dua nilai sederhana, tanpa efek samping. Begitu salah satu syarat itu pecah — kondisi berlapis, ternary di dalam ternary, atau pemanggilan method yang mengubah data — kode if/else biasa jauh lebih mudah dirawat. Untuk membandingkan satu nilai terhadap banyak kandidat, PHP 8 juga menyediakan ekspresi match yang jauh lebih rapi (dibahas tuntas pada Chapter Match Expression
):
<?php
$nilai = 85;
$predikat = match (true) {
$nilai >= 90 => "A",
$nilai >= 80 => "B",
$nilai >= 70 => "C",
default => "D",
};
echo "Predikat: $predikat\n";Output yang Dihasilkan:
Predikat: BEkspresi match (true) mengevaluasi setiap kondisi dari atas ke bawah dan menghasilkan nilai dari cabang pertama yang cocok — hasil yang sama dengan ternary bertingkat di atas, tanpa tanda kurung bertumpuk dan tanpa pengulangan ? :. Bedanya, match membandingkan dengan perbandingan ketat (=== — dibahas pada Chapter Operator Identitas
) dan tanpa cabang default yang cocok ia melempar UncaughtMatchError. Berkas contoh.php pada bagian bawah halaman merangkum seluruh varian pemilihan nilai dari Chapter ini.
Ringkasan #
Ternary operator memilih satu dari dua nilai dalam satu ekspresi: kondisi ? a : b, dengan bentuk pendek nilai ?: cadangan untuk kasus “kecuali kosong”. Operator ?: bekerja dengan logika truthiness dan memicu peringatan pada variabel yang tidak ada, sedangkan ?? hanya peduli null dan aman untuk data opsional. Ternary bertingkat wajib memakai tanda kurung sejak PHP 8, dan begitu logika pilihan mulai bertingkat, if/else atau match adalah alat yang lebih tepat. Selanjutnya kita bertemu operator perbandingan yang mengembalikan tiga kemungkinan sekaligus: spaceship operator.
Referensi #
- Dokumentasi operator perbandingan (ternary dan ??) — php.net
- Struktur kontrol if — php.net
- Ekspresi match — php.net
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh.php
Unduh berkas<?php
// contoh.php — rangkuman Ternary Operator
// Jalankan dengan: php contoh.php
// 1. Bentuk lengkap: kondisi ? nilaiBenar : nilaiSalah
$usia = 20;
$status = $usia >= 17 ? "dewasa" : "anak-anak";
echo "Status : $status\n";
// 2. Bentuk pendek: nilai ?: nilaiCadangan (berbasis truthiness)
$namaPanggilan = "";
$namaTampilan = $namaPanggilan ?: "Tamu";
echo "Sapaan : $namaTampilan\n";
$stok = 0;
echo "Label stok : " . ($stok ?: "habis") . "\n";
// 3. Perbedaan ?: dan ??
$diskon = 0;
echo "Diskon ?? : " . ($diskon ?? 10) . "\n";
echo "Diskon ?: : " . ($diskon ?: 10) . "\n";
// 4. Data yang mungkin tidak ada -> selalu pakai ??
$tema = $preferensiPengguna ?? "terang";
echo "Tema : $tema\n";
// 5. Ternary bertingkat wajib memakai tanda kurung
$nilai = 85;
$predikat = $nilai >= 90 ? "A" : ($nilai >= 80 ? "B" : ($nilai >= 70 ? "C" : "D"));
echo "Predikat : $predikat\n";
// 6. Alternatif yang lebih rapi untuk banyak cabang: match
$predikatMatch = match (true) {
$nilai >= 90 => "A",
$nilai >= 80 => "B",
$nilai >= 70 => "C",
default => "D",
};
echo "Predikat : $predikatMatch\n";