Data opsional dalam aplikasi sering membentuk rantai: seorang pelanggan mungkin punya alamat, alamat tersebut mungkin punya kota. Ketika salah satu mata rantai bernilai null, akses lanjutan dengan tanda panah biasa (->) langsung menghentikan program dengan fatal error. Nullsafe operator (?->), yang hadir sejak PHP 8.0, memungkinkan kita menulis akses berantai tersebut dalam satu ekspresi yang aman: jika objeknya null, hasil seluruh rantai adalah null — bukan error. Pada Chapter ini kita akan mempelajari cara kerja ?->, cara menggabungkannya dengan ??, serta batasan-batasan pentingnya.
Sebelum mulai, kita perlu sedikit konteks tentang class dan object karena ?-> hanya relevan di sana. Class adalah cetak biru objek; properti adalah variabel di dalam objek; dan method adalah fungsi di dalam objek. Operator -> dipakai untuk mengakses keduanya: $pelanggan->nama membaca properti $nama, sedangkan $pelanggan->kota() memanggil method kota(). Materi lengkapnya ada di Section Object-Oriented Programming; untuk Chapter ini cukup tiga contoh class kecil di bawah sudah lebih dari cukup.
Masalah Akses pada Objek null #
Perhatikan class Alamat yang punya method kota(), dan class Pelanggan yang properti $alamat-nya boleh null (ditandai tipe ?Alamat). Ketika properti tersebut memang null, akses method di bawahnya menjadi bencana:
<?php
class Alamat {
public function kota(): string {
return "Bandung";
}
}
class Pelanggan {
public ?Alamat $alamat = null;
}
$budi = new Pelanggan();
echo $budi->alamat->kota();Kode di atas lolos pemeriksaan sintaks, tetapi gagal total saat dijalankan karena $budi->alamat bernilai null:
Fatal error: Uncaught Error: Call to a member function kota() on null in contoh.php on line 13Pesan di atas diambil dari eksekusi nyata — nama berkas dan nomor baris di komputer Anda akan menyesuaikan lokasi penulisan tersebut.
Pesan Call to a member function kota() on null berarti PHP diminta memanggil method pada “bukan objek”. Selama bertahun-tahun solusinya adalah memeriksa null secara manual di setiap tingkat rantai — membengkak dan membosankan bila rantainya panjang. Perilaku fatal error ini juga menjadi alasan kenapa pengecekan null pada objek opsional termasuk rutinitas paling sering ditulis di aplikasi nyata.
Solusi dengan Operator ?-> #
Nullsafe operator mengubah tanda panah -> menjadi ?->: jika operand kirinya bukan null, akses berjalan normal; jika null, ekspresi menghasilkan null tanpa error:
<?php
class Alamat {
public function kota(): string {
return "Bandung";
}
}
class Pelanggan {
public ?Alamat $alamat = null;
}
$siti = new Pelanggan();
$siti->alamat = new Alamat();
$budi = new Pelanggan();
echo ($siti->alamat?->kota() ?? "alamat kosong") . "\n";
echo ($budi->alamat?->kota() ?? "alamat kosong") . "\n";Output yang Dihasilkan:
Bandung
alamat kosongMari kita bedah baris-baris kuncinya:
- Baris 12-13 (
$siti): properti$alamatdiisi objekAlamatsungguhan, sehingga$siti->alamat?->kota()mengevaluasikota()secara normal dan menghasilkan"Bandung". - Baris 15 (
$budi): properti$alamattetapnull. Tanda?->mendeteksi hal tersebut dan langsung menghasilkannull— methodkota()tidak pernah dipanggil, tidak ada fatal error. - Baris 17-18: kombinasi dengan
??dari Chapter Null Coalescing Operator mengubahnullmenjadi teks cadangan"alamat kosong".
Tanpa ?->, kita membutuhkan pemeriksaan if bersarang untuk kasus dua tingkat ini, dan pemeriksaan bertambah setiap kali rantai bertambah satu tingkat. Dengan ?->, panjang rantai tidak mengubah kompleksitas kode sama sekali.
Rantai Akses yang Lebih Panjang #
Kekuatan sesungguhnya baru terasa pada rantai multi-tingkat. Perhatikan tiga class berikut: Profil berisi ?Kota, dan Kota berisi ?Negara. Mengambil kode mata uang dari profil berarti melintasi dua mata rantai yang sama-sama bisa null:
<?php
class Negara {
public function kodeMataUang(): string {
return "IDR";
}
}
class Kota {
public ?Negara $negara = null;
}
class Profil {
public ?Kota $kota = null;
}
$profil = new Profil();
var_dump($profil->kota?->negara?->kodeMataUang());
$profil->kota = new Kota();
$profil->kota->negara = new Negara();
echo ($profil->kota?->negara?->kodeMataUang() ?? "mata uang tidak diketahui") . "\n";Output yang Dihasilkan:
NULL
IDRSaat $profil->kota masih null, ekspresi $profil->kota?->negara?->kodeMataUang() langsung menghasilkan null — sisa rantai di sebelah kanannya (termasuk pemanggilan kodeMataUang()) tidak dievaluasi sama sekali. Setelah kedua mata rantai terisi objek, hasilnya "IDR". Perhatikan bahwa pemberian nilai di baris 15-16 tetap memakai -> biasa; ?-> hanya berperan di sisi pembacaan nilai.
Sifat “menghentikan seluruh rantai” ini berlaku juga saat ?-> dicampur dengan -> biasa. Ekspresi $profil->kota?->negara->kodeMataUang() (hanya tanda panah pertama yang nullsafe) tetap menghasilkan null tanpa error ketika $profil->kota adalah null, karena evaluasi seluruh ekspresi berhenti di titik tersebut.
Hanya null yang Di-skip #
Nullsafe operator menyingkat jalur untuk null — bukan untuk nilai lain yang dianggap falsy PHP. Jika objeknya ada, method di dalamnya tetap dipanggil sekalipun nilai kembaliannya nol atau string kosong:
<?php
class Keranjang {
public function totalItem(): int {
return 0;
}
}
class Pengguna {
public ?Keranjang $keranjang = null;
}
$pengguna = new Pengguna();
$pengguna->keranjang = new Keranjang();
var_dump($pengguna->keranjang?->totalItem());
var_dump($pengguna->keranjang?->totalItem() ?? "keranjang kosong");
$penggunaLain = new Pengguna();
var_dump($penggunaLain->keranjang?->totalItem() ?? "keranjang kosong");Output yang Dihasilkan:
int(0)
int(0)
string(16) "keranjang kosong"Baris var_dump pertama membuktikan method totalItem() benar-benar dieksekusi dan mengembalikan int(0). Baris kedua memperlihatkan jebakan klasik: 0 ?? "keranjang kosong" tetap menghasilkan int(0) karena 0 bukan null — operator ?? tidak menggantinya. Hanya pada baris terakhir, ketika $keranjang benar-benar null, nilai cadangan "keranjang kosong" yang muncul. Logika ?-> dan ?? sama-sama hanya mengurus null; keduanya sengaja tidak menyentuh nilai falsy lain (pembahasan lengkap ada di Chapter Truthiness dan Short-Circuit
).
Batasan Operator Nullsafe #
Nullsafe operator adalah operator pembacaan nilai, bukan penulisan. PHP menolak ?-> di sisi kiri tanda sama dengan (=), sehingga kode berikut tidak pernah berhasil dijalankan:
<?php
class Pelanggan {
public ?string $nama = null;
}
$pelanggan = null;
$pelanggan?->nama = "Budi";Pesan fatal yang muncul saat kode di atas dijalankan:
Fatal error: Can't use nullsafe operator in write context in contoh.php on line 8Pesan di atas diambil dari eksekusi nyata dengan kode blok sebelumnya disimpan sebagai contoh.php; nomor baris di komputer Anda menyesuaikan. Alasannya masuk akal: bila $pelanggan adalah null, tidak ada objek yang bisa menampung penugasan nama = "Budi", jadi PHP memilih menolaknya di awal daripada diam-diam membuang nilai. Untuk mengisi properti, pastikan objeknya ada lebih dulu — misalnya dengan membuat objek terlebih dahulu seperti contoh $siti->alamat = new Alamat(); di atas.
Selain itu, ?-> hanya boleh dipakai saat Anda tidak peduli perbedaan antara “objeknya null” dan “objeknya ada”. Bila kedua kasus tersebut butuh perlakuan berbeda — misalnya mencatat log khusus untuk data yang hilang — tulis pemeriksaan null eksplisit agar logika terlihat jelas. Berkas contoh.php pada bagian bawah halaman merangkum pola-pola aman dari Chapter ini dalam satu program utuh.
Ringkasan #
Operator ?-> mengevaluasi akses method atau properti hanya bila objek di kirinya bukan null; jika null, seluruh rantai ekspresi berhenti dan menghasilkan null tanpa error. Kombinasi ?-> dengan ?? menghasilkan pola baca data opsional berantai yang ringkas dan aman, sementara penugasan tetap membutuhkan objek yang benar-benar ada. Selanjutnya kita berpindah ke operator pemilih nilai yang bekerja pada kondisi umum: ternary operator.
Referensi #
- Dasar-dasar OOP: properti dan method — php.net
- Fitur baru PHP 8.0 (nullsafe operator) — php.net
- Dokumentasi operator perbandingan (??) — 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 Nullsafe Operator
// Jalankan dengan: php contoh.php
class Alamat {
public function kota(): string {
return "Bandung";
}
}
class Pelanggan {
public ?Alamat $alamat = null;
}
$siti = new Pelanggan();
$siti->alamat = new Alamat();
$budi = new Pelanggan();
echo "Kota Siti : " . ($siti->alamat?->kota() ?? "alamat kosong") . "\n";
echo "Kota Budi : " . ($budi->alamat?->kota() ?? "alamat kosong") . "\n";
// Rantai multi-tingkat
class Negara {
public function kodeMataUang(): string {
return "IDR";
}
}
class Kota {
public ?Negara $negara = null;
}
class Profil {
public ?Kota $kota = null;
}
$profil = new Profil();
echo "Mata uang : " . var_export($profil->kota?->negara?->kodeMataUang(), true) . "\n";
$profil->kota = new Kota();
$profil->kota->negara = new Negara();
echo "Mata uang : " . ($profil->kota?->negara?->kodeMataUang() ?? "mata uang tidak diketahui") . "\n";
// Hanya null yang di-skip: method tetap dipanggil walau hasilnya 0
class Keranjang {
public function totalItem(): int {
return 0;
}
}
class Pengguna {
public ?Keranjang $keranjang = null;
}
$pengguna = new Pengguna();
$pengguna->keranjang = new Keranjang();
echo "Keranjang : " . var_export($pengguna->keranjang?->totalItem(), true) . "\n";
$penggunaLain = new Pengguna();
echo "Keranjang : " . ($penggunaLain->keranjang?->totalItem() ?? "keranjang kosong") . "\n";