Kadang jawaban yang jujur atas sebuah pertanyaan adalah “tidak ada”: peserta tanpa nomor telepon, pengaturan yang belum pernah diubah, kolom formulir yang dibiarkan kosong. PHP merepresentasikan ketiadaan nilai itu dengan null — nilai khusus yang merupakan satu-satunya anggota tipenya sendiri. Pada Chapter ini kita bedah makna null, perbedaannya dengan variabel yang belum didefinisikan, cara mengambil nilai dengan aman melalui operator ??, dan sekilas tentang nullable types yang menjadi fondasi penanganan “nilai mungkin tidak ada” di PHP modern.

Nilai null dan Tipe null #

null adalah nilai sekaligus tipe: sebuah variabel bernilai null bertipe null, terpisah dari string, integer, maupun boolean. Penulisannya tidak sensitif terhadap kapitalisasi, sama seperti true dan false:

php
<?php
$telepon = null;

var_dump($telepon);
var_dump(is_null($telepon));
var_dump($telepon === null);
var_dump(gettype($telepon));

Output yang Dihasilkan:

text
NULL
bool(true)
bool(true)
string(4) "NULL"

var_dump() menampilkan NULL dengan huruf besar, dan gettype() mengembalikan string "NULL" — menegaskan bahwa null adalah tipenya sendiri. Cara paling eksplisit memeriksa null adalah perbandingan ketat $telepon === null; fungsi is_null() memberi hasil yang sama. Tapi seperti akan kita lihat, keduanya berbeda secara halus ketika variabelnya belum pernah ada.

null Bukan Variabel yang Belum Didefinisikan #

Variabel yang belum pernah diberi nilai dan variabel yang diberi null adalah dua keadaan berbeda — meski keduanya “tidak berisi apa-apa”. Operator isset() memperlakukan keduanya sama-sama hilang:

php
<?php
$nama = null;
unset($email);

var_dump(isset($nama), isset($email));

Output yang Dihasilkan:

text
bool(false)
bool(false)

Baik $nama (sengaja di-null-kan) maupun $email (dihapus dengan unset()) sama-sama membuat isset() mengembalikan false — operator ini menganggap nilai null sebagai “tidak terpasang”. Perbedaannya baru terlihat ketika variabel dibaca langsung. Simpan berikut sebagai cek-null.php:

php
<?php
$nama = null;
unset($email);

var_dump(is_null($nama));
var_dump(is_null($email));

Output yang Dihasilkan:

text
bool(true)

Warning: Undefined variable $email in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/null/.verify_tmp.php on line 6
bool(true)

Kedua panggilan is_null() mengembalikan true, tetapi yang kedua diawali Warning: Undefined variable $email — membaca variabel yang belum pernah didefinisikan memicu peringatan, sementara variabel bernilai null aman dibaca. Jadi null adalah cara sopan menyatakan “sengaja kosong”: variabelnya ada, nilainya tidak.

unset vs Penugasan null #

Perbedaan “mengosongkan” vs “menghapus” paling nyata pada key array. Memberi nilai null tetap menyimpan key-nya; unset() mencabut key itu dari array:

php
<?php
$peserta = ["nama" => "Budi", "telepon" => null];

var_dump(isset($peserta["telepon"]));
var_dump(array_key_exists("telepon", $peserta));

unset($peserta["telepon"]);

var_dump(array_key_exists("telepon", $peserta));
var_dump(count($peserta));

Output yang Dihasilkan:

text
bool(false)
bool(true)
bool(false)
int(1)

Saat telepon bernilai null, isset() mengembalikan false tetapi array_key_exists() mengembalikan true — key-nya masih ada, hanya nilainya null. Setelah unset(), key tersebut hilang sama sekali: array_key_exists() menjadi false dan count() turun menjadi 1. Pilih sesuai makna yang Anda maksud: null berarti “data ini diketahui tidak ada isinya”, unset berarti “data ini tidak pernah relevan”.

Null Coalescing Operator #

Membaca nilai yang mungkin null — atau mungkin belum ada — adalah rutinitas harian. Operator null coalescing ?? mengembalikan nilai di sisi kanan hanya bila sisi kirinya null atau tidak terdefinisi, tanpa memicu warning apa pun:

php
<?php
$pengaturan = ["tema" => "gelap", "bahasa" => null];

var_dump($pengaturan["tema"] ?? "terang");
var_dump($pengaturan["bahasa"] ?? "id");
var_dump($pengaturan["zona"] ?? "Asia/Jakarta");

Output yang Dihasilkan:

text
string(5) "gelap"
string(2) "id"
string(12) "Asia/Jakarta"

Ketiga baris memperlihatkan tiga keadaan: tema terisi sehingga nilainya dipakai; bahasa bernilai null sehingga diganti "id"; zona bahkan tidak ada sebagai key — dan ?? tetap tenang tanpa warning, karena pemeriksaannya setara isset(). Operator ini juga bisa dirantai untuk mencoba beberapa sumber secara berurutan:

php
<?php
$pengaturan = ["bahasa" => null];

var_dump($pengaturan["zona"] ?? $pengaturan["bahasa"] ?? "id");

Output yang Dihasilkan:

text
string(2) "id"

Rantai dibaca dari kiri: zona tidak ada, bahasa null, jadi jatuh ke cadangan terakhir "id".

Preview Nullable Types dan Nullsafe Operator #

Dua fitur PHP modern dibangun di atas null. Yang pertama adalah nullable type — menulis tanda tanya sebelum nama tipe, seperti ?string, untuk menyatakan bahwa sebuah property atau parameter boleh bernilai null. Yang kedua adalah nullsafe operator ?-> yang mengakses property tanpa takut objeknya null:

php
<?php
class Pengguna {
    public string $nama = "Budi";
    public ?string $kota = null; // tipe nullable: boleh null
}

$pengguna = new Pengguna();
var_dump($pengguna->kota);
var_dump($pengguna->kota ?? "Tidak diketahui");

$admin = null;
var_dump($admin?->nama ?? "Pengguna tidak dikenal");

Output yang Dihasilkan:

text
NULL
string(15) "Tidak diketahui"
string(22) "Pengguna tidak dikenal"

Keyword class dan new akan dibedah tuntas pada Chapter Objects — untuk sekarang, fokus pada tanda ?. Akses $admin?->nama pada variabel null mengembalikan null dengan tenang, padahal versi tanpa tanda ($admin->nama) menghentikan program. Kombinasi ?-> dan ?? menghasilkan rantai akses yang aman penuh.

Perilaku null dalam Operasi #

Terakhir, mari amati apa yang terjadi ketika null ikut beroperasi. Dalam konteks angka null menjadi 0, dalam konteks string menjadi "", dan dalam perbandingan longgar == null setara dengan nilai-nilai falsy:

php
<?php
var_dump(null + 1);
var_dump("Halo, " . null);
var_dump(null == false, null == 0, null == "", null == []);
var_dump(null == "0");
var_dump(null === false);

Output yang Dihasilkan:

text
int(1)
string(6) "Halo, "
bool(true)
bool(true)
bool(true)
bool(true)
bool(false)
bool(false)

null + 1 menghasilkan 1 dan penggabungan "Halo, " . null menghasilkan "Halo, " — null melunak menjadi identitas operasi. Empat perbandingan longgar pertama true, tetapi null == "0" justru false (null dibandingkan sebagai string kosong, dan "" == "0" tidak sama), dan null === false false karena tipe keduanya berbeda. Aturan-aturan konversi ini adalah bagian dari mekanisme type juggling yang akan kita petakan tuntas pada chapter penutup section ini.

Ringkasan #

null adalah tipe sekaligus nilai untuk “tidak ada”: aman dibaca lewat is_null() atau === null, tetapi tak terlihat oleh isset(). Penugasan null menjaga keberadaan key, sementara unset() menghapusnya. Operator ?? dan ?-> menangani nilai-mungkin-null secara ringkas dan aman, dan null berperilaku seperti 0, "", atau false mengikuti konteks operasinya. Setelah delapan tipe nilai, kita berjumpa dengan tipe komposit pertama yang mengubah cara Anda mengorganisir data: array.

Referensi #