Chapter null
telah menegaskan bahwa null adalah penanda “tidak ada nilai”, bukan sekadar nol atau string kosong. Pada dunia nyata, kehadiran null justru lazim: nama panggilan pengguna yang belum diisi, tanggal pembatalan pesanan yang belum terjadi, atau hasil pencarian yang gagal. Nullable types memungkinkan kita mendeklarasikan tipe yang secara eksplisit menerima null — ?string berarti “string atau null”. Pada Chapter ini kita mempelajari sintaksnya untuk parameter, nilai kembali, dan property, lalu menutup dengan aturan PHP 8.4 yang melarang bentuk lama implicitly-nullable.
Sintaks ?T pada Parameter dan Nilai Kembali #
Tanda tanya ditulis tepat sebelum nama tipe untuk menyatakan bahwa null juga diterima. Deklarasi tersebut berlaku untuk parameter maupun nilai kembali fungsi:
<?php
function cariNickname(?string $nama): ?string
{
if ($nama === null) {
return null;
}
return strtolower(str_replace(" ", ".", $nama));
}
var_dump(cariNickname("Budi Santoso"));
var_dump(cariNickname(null));Output yang Dihasilkan:
string(12) "budi.santoso"
NULLMari kita bedah fungsinya. Parameter ?string $nama menerima string sekaligus null; tanpa tanda tanya, pemanggilan cariNickname(null) akan langsung ditolak PHP. Demikian pula nilai kembali ?string menyatakan bahwa fungsi boleh mengembalikan null — tepat untuk fungsi pencarian yang gagal menemukan hasil. Panggilan pertama mengubah "Budi Santoso" menjadi nickname "budi.santoso", sedangkan panggilan kedua mengembalikan null apa adanya.
Property Nullable pada Class #
Sejak PHP 7.4, property class juga dapat diberi type declaration, termasuk bentuk nullable. Property nullable memiliki keistimewaan: property tersebut boleh diberi nilai awal null:
<?php
class Akun
{
public string $nama;
public ?string $nickname = null;
public function __construct(string $nama)
{
$this->nama = $nama;
}
}
$akun = new Akun("Siti");
var_dump($akun->nama);
var_dump($akun->nickname);
$akun->nickname = "siti_99";
var_dump($akun->nickname);Output yang Dihasilkan:
string(4) "Siti"
NULL
string(7) "siti_99"Property $nama bertipe string wajib diisi lewat constructor, sedangkan $nickname bertipe ?string aman dimulai dari null — bayangkan pengguna yang baru mendaftar dan belum menulis nickname. Setelah baris $akun->nickname = "siti_99" dijalankan, property tersebut berisi string dan var_dump melaporkannya. Pemeriksaan $akun->nickname === null kini bisa dipakai untuk membedakan “belum diisi” dari “sudah diisi”.
Parameter Implicitly Nullable Sudah Usang #
Sebelum sintaks ?T populer, banyak kode lama menulis parameter nullable dengan cara tersembunyi: memberi nilai awal null pada parameter yang tipenya tidak nullable, seperti string $nama = null. PHP 8.4 menandai gaya tersebut sebagai usang. Simpan kode berikut sebagai sapa.php lalu jalankan:
<?php
function sapa(string $nama = null): ?string
{
return $nama === null ? null : "Halo, $nama!";
}
var_dump(sapa(null));
var_dump(sapa("Budi"));Output yang Dihasilkan:
Deprecated: sapa(): Implicitly marking parameter $nama as nullable is deprecated, the explicit nullable type must be used instead in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php on line 2
NULL
string(11) "Halo, Budi!"Program tetap berjalan sampai akhir — Deprecated adalah peringatan, bukan penghenti eksekusi — tetapi pesannya tegas: parameter $nama ditandai nullable secara diam-diam, dan bentuk eksplisit harus dipakai. PHP akan meningkatkan pelanggaran ini menjadi error pada versi mendatang, jadi kode baru harus langsung menulis bentuk yang benar:
<?php
function sapa(?string $nama = null): ?string
{
return $nama === null ? null : "Halo, $nama!";
}
var_dump(sapa(null));
var_dump(sapa("Budi"));Output yang Dihasilkan:
NULL
string(11) "Halo, Budi!"Satu karakter tanda tanya menghilangkan peringatan tersebut: ?string $nama = null kini menyatakan niatnya secara jujur — parameter boleh null dan nilai awalnya memang null. Bentuk ini pula yang dihasilkan oleh alat modernisasi otomatis seperti Rector, dan menjadi standar pada panduan gaya komunitas.
null Bukan Anggota Bebas #
Kesalahan umum berikutnya adalah menganggap null selalu lolos ke parameter apa pun. Kenyataannya, parameter non-nullable menolak null bahkan di mode lemah sekalipun — null tidak pernah dikonversi diam-diam menjadi 0 atau string kosong. Simpan sebagai hitung.php:
<?php
function proses(int $jumlah): int
{
return $jumlah * 2;
}
var_dump(proses(null));Output yang Dihasilkan:
Fatal error: Uncaught TypeError: proses(): Argument #1 ($jumlah) must be of type int, null given, called in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php on line 7 and defined in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php:2
Stack trace:
#0 /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php(7): proses(NULL)
#1 {main}
thrown in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php on line 2Pesan TypeError di atas menegaskan kontraknya: parameter bertipe int hanya menerima integer. Bila null memang kemungkinan yang wajar, tipe parameter harus dinyatakan nullable dan fungsi menanganinya secara eksplisit — misalnya dengan memberi nilai cadangan melalui operator ?? yang telah kita kenal pada Chapter Superglobals
.
Terakhir, ada dua cara penulisan yang setara: ?int hanyalah singkatan dari int|null. Keduanya boleh dipakai untuk deklarasi nullable, dan pemilihan di antara keduanya adalah selera gaya:
<?php
function pangkatDua(int|null $basis): ?int
{
if ($basis === null) {
return null;
}
return $basis ** 2;
}
var_dump(pangkatDua(null));
var_dump(pangkatDua(3));Output yang Dihasilkan:
NULL
int(9)Yang tidak boleh adalah menggabungkan tanda tanya dengan tipe union — ?int|string invalid karena ? hanya boleh membungkus satu tipe:
<?php
function proses(?int|string $nilai)
{
}Output yang Dihasilkan:
Parse error: syntax error, unexpected token "|", expecting variable in /home/z/my-project/php-course/content/php/tipe-data-dan-type-system/nullable-types/.verify_tmp.php on line 2Parser PHP menolaknya sebelum program sempat berjalan karena aturannya jelas: ? adalah singkatan yang hanya berlaku untuk satu tipe. Bila yang dimaksud adalah “integer, string, atau null”, tuliskan ketiganya sebagai anggota union: int|string|null — sintaks yang akan kita bahas tuntas pada Chapter berikutnya.
Ringkasan #
Sintaks ?T mendeklarasikan tipe yang menerima null pada parameter, nilai kembali, maupun property; ?int setara dengan int|null, dan null tetap ditolak keras oleh parameter non-nullable. PHP 8.4 melarang bentuk lama string $x = null melalui peringatan Deprecated, jadi selalu tulis ?string $x = null. Satu tipe ditambah null pun selesai — pada Chapter berikutnya kita memperluas jangkauan deklarasi ke lebih dari satu tipe sekaligus dengan union types.