Sejak PHP 8.0 dirilis pada akhir 2020, PHP beralih ke siklus rilis tahunan: satu versi utama baru tiap akhir tahun, dengan masa dukungan bugfix dua tahun dan masa dukungan keamanan dua tahun berikutnya. Chapter-chapter sebelumnya pada section ini telah membedah fitur-fitur besarnya satu per satu, mulai dari named arguments hingga property hooks. Kali ini kita menarik diri sedikit ke belakang untuk melihat peta keseluruhan: fitur apa yang datang di tiap versi dan masalah lama apa yang diselesaikannya. Peta semacam ini berguna ketika Anda membaca kode warisan (legacy code), menimbang upgrade, atau memutuskan fitur mana yang aman dipakai di proyek Anda. Seluruh contoh pada chapter ini diuji pada PHP 8.4, sehingga setiap fitur dari 8.0 sampai 8.4 dapat dijalankan langsung.
Peta Fitur per Versi #
Tabel berikut merangkum fitur andalan tiap versi beserta masalah lama yang dijawabnya. Gunakan tabel ini sebagai indeks cepat — setiap fitur yang disebut memiliki chapter khusus di section ini bila ingin diperdalam.
| Versi | Fitur Andalan | Masalah Lama yang Dijawab |
|---|---|---|
| 8.0 | Named arguments, match, nullsafe ?->, union types, constructor property promotion, JIT | Urutan argumen yang kaku, switch yang bertele-tele, pengecekan null berantai, nilai kembali tanpa batasan tipe |
| 8.1 | Enums, readonly property, first-class callable, intersection types, never, fibers | Konstanta class sebagai “enum palsu”, property yang bisa diubah diam-diam, Closure::fromCallable() yang panjang |
| 8.2 | Readonly class, tipe true/false/null berdiri sendiri, DNF types | Kata kunci readonly yang diulang di tiap property, tipe bool yang terlalu luas untuk kasus yang pasti |
| 8.3 | json_validate(), atribut #[\Override], typed class constants | json_decode() yang boros hanya untuk mengecek validitas, kekeliruan nama method saat override tidak terdeteksi |
| 8.4 | Property hooks, asymmetric visibility, new tanpa kurung, mb_trim(), array_find()/array_any()/array_all(), lazy objects | Getter/setter boilerplate, visibilitas baca dan tulis yang terpaksa seragam, trim() yang buta terhadap Unicode |
PHP 8.0 — Fondasi Bahasa Modern #
PHP 8.0 adalah lompatan terbesar dalam satu dekade karena mengubah sintaks harian sekaligus fondasi engine. Named arguments membebaskan pemanggil dari hafalan urutan parameter, match mengembalikan nilai tanpa perlu break, dan nullsafe operator ?-> memotong rangkaian if pengecekan null. Union types membuka jalan menuju type system yang kaya — pokok bahasan Section berikutnya. Sementara itu, JIT (Just In Time compiler) mempercepat beban kerja numerik yang berat; efeknya dirasakan pada performa, bukan pada output program.
<?php
// Named arguments: urutan bebas, arti argumen jelas
function buatKopi(string $jenis, int $gula = 1, bool $panas = true): string
{
return $gula . " sachet gula, kopi " . $jenis . ($panas ? " panas" : " dingin");
}
echo buatKopi(gula: 2, jenis: "Gayo") . "\n";
// Match: cabang berbasis nilai yang langsung mengembalikan nilai
$kode = 200;
echo match (true) {
$kode >= 200 && $kode < 300 => "sukses",
$kode >= 400 => "galat klien",
default => "tidak dikenal",
} . "\n";
// Nullsafe: menelusuri null tanpa if bertingkat
$pengguna = null;
echo ($pengguna?->alamat?->kota) ?? "alamat kosong" . "\n";
// Union types: satu deklarasi untuk beberapa kemungkinan tipe
function totalBelanja(int|float ...$item): int|float
{
return array_sum($item);
}
echo totalBelanja(10000, 2.5) . "\n";Output yang Dihasilkan:
2 sachet gula, kopi Gayo panas
sukses
alamat kosong
10002.5Empat fitur bekerja bersama dalam satu berkas tersebut:
- Named arguments — pemanggilan
buatKopi(gula: 2, jenis: "Gayo")melompati parameter$panastanpa harus mengisitruesecara eksplisit; setiap argumen menyebut namanya sendiri sehingga urutan bebas. match— ekspresimatch (true)mengevaluasi tiap arm dari atas; arm pertama yang bernilai benar menang, tanpabreakdan tanpa risiko fall-through seperti padaswitch.- Nullsafe —
$pengguna?->alamat?->kotaberhenti aman menghasilkannullbegitu salah satu ruas bernilainull; operator??kemudian menyediakan nilai cadangan. - Union types —
int|floatpada parameter variadic maupun return type menyatakan bahwa kedua jenis angka sama-sama diterima.
Bedah tuntas tiap fitur tersedia di chapter Named Arguments , Match Expressions , Nullsafe Operator , dan Union Types .
PHP 8.1 — Enum, Readonly, dan First-Class Callable #
PHP 8.1 menyumbang dua fitur struktural yang paling sering dipakai kode modern: enum untuk himpunan nilai tetap dan readonly property untuk nilai yang terkunci setelah konstruksi. First-class callable syntax strlen(...) menggantikan Closure::fromCallable('strlen') yang panjang. Intersection types mempertajam union types dengan menyaratkan sebuah nilai memenuhi beberapa tipe sekaligus, return type never menandai fungsi yang tidak pernah kembali, dan fibers memberi blok bangunan eksekusi kooperatif bagi pustaka kode asinkron.
<?php
enum StatusPesanan: string
{
case Baru = "baru";
case Diproses = "diproses";
case Selesai = "selesai";
}
$label = match (StatusPesanan::Diproses) {
StatusPesanan::Baru => "pesanan baru masuk",
StatusPesanan::Diproses => "pesanan sedang dikemas",
StatusPesanan::Selesai => "pesanan sudah dikirim",
};
echo $label . "\n";
class Harga
{
public function __construct(public readonly int $jumlah) {}
}
echo (new Harga(15000))->jumlah . "\n";
$panjang = strlen(...);
echo $panjang("PHP modern") . "\n";Output yang Dihasilkan:
pesanan sedang dikemas
15000
10Mari kita bedah contoh tersebut:
- Enum —
StatusPesananmendefinisikan tiga kemungkinan status sebagai case dengan backing value string;matchpada objek enum (tanpa->value) membandingkan identitas case, bukan teks stringnya. Karena seluruh case terdaftar, tidak ada jalur status yang terlewat. - readonly property + promotion —
public readonly int $jumlahdigabung dengan constructor property promotion (fitur 8.0): parameter constructor sekaligus menjadi property terkunci yang tidak bisa ditulis ulang. - First-class callable —
strlen(...)membungkus fungsi global menjadiClosuretanpa perlu string nama fungsi; hasilnya lalu dipanggil seperti fungsi biasa.
Pembahasan mendalam ada di chapter Enums , Readonly Properties dan Classes , Intersection Types , Never Return Type , dan Fibers .
PHP 8.2 — Readonly Class dan Tipe Baru #
PHP 8.2 menyempurnakan dua fitur pendahulunya. Kata kunci readonly kini dapat menempel pada class sehingga seluruh property terkunci sekaligus — tidak perlu mengulang readonly di tiap property. Tipe true, false, dan null kini boleh berdiri sendiri, sehingga fungsi yang pasti mengembalikan true saat sukses dapat menyatakannya secara jujur. DNF types melengkapi keduanya dengan mengizinkan gabungan intersection dan union dalam satu deklarasi, misalnya (Countable&Iterator)|null.
<?php
readonly class Kredensial
{
public function __construct(
public string $pengguna,
public string $token,
) {}
}
$kredensial = new Kredensial("budi", "YOUR_API_TOKEN");
echo $kredensial->pengguna . "\n";
function koneksiSiap(): true
{
return true;
}
var_dump(koneksiSiap());Output yang Dihasilkan:
budi
bool(true)Tiga hal terjadi pada contoh di atas:
- readonly class — satu kata kunci
readonlydi depanclassmembuat kedua property promoted di dalamnya terkunci; penugasan ulang seperti$kredensial->token = "x"setelah konstruksi memicuError. - Tipe
true— return typetruemenyatakan bahwa satu-satunya nilai yang mungkin dikembalikan adalahtrue; fungsi pengece keberhasilan menjadi jujur secara tipe. Tipefalsedannullberdiri sendiri dengan cara yang sama. - Placeholder kredensial — nilai
YOUR_API_TOKENsengaja berupa penampung; jangan pernah menaruh token nyata di dalam kode.
PHP 8.3 — Validasi JSON dan Atribut Override #
PHP 8.3 berfokus pada ketelitian. Fungsi json_validate() menjawab kebutuhan yang sangat umum: memeriksa validitas JSON tanpa harus mendekode seluruh dokumen. Atribut #[\Override] membuat niat menimpa method parent menjadi eksplisit — jika ternyata tidak ada method yang ditimpa, PHP menolak sejak deklarasi class, sehingga kekeliruan nama akibat refactor langsung ketahuan. Typed class constants menutup celah terakhir pada sistem tipe: konstanta kini punya type declaration layaknya property.
<?php
class Pemformat
{
const string PEMISAH = "-";
public static function gabung(string ...$bagian): string
{
return implode(self::PEMISAH, $bagian);
}
}
echo Pemformat::gabung("PHP", "8", "3") . "\n";
var_dump(json_validate('{"versi": "8.3"}'));
var_dump(json_validate('{versi: 8.3}'));
class PemformatLoud extends Pemformat
{
#[\Override]
public static function gabung(string ...$bagian): string
{
return strtoupper(parent::gabung(...$bagian));
}
}
echo PemformatLoud::gabung("php", "8", "3") . "\n";Output yang Dihasilkan:
PHP-8-3
bool(true)
bool(false)
PHP-8-3Mari kita bedah fitur-fiturnya:
- Typed class constant —
const string PEMISAHmemaksa konstanta berjenis string; penugasan dengan tipe lain akan gagal, dan editor pun bisa mengandalkan tipe tersebut. json_validate()— mengembalikanbooltanpa membangun struktur data apa pun; teks{versi: 8.3}memang bukan JSON valid karena kunci tidak berada dalam tanda kutip.#[\Override]— menegaskan bahwaPemformatLoud::gabung()sengaja menimpa method parent; bila nama method parent suatu saat berubah atau salah ketik, PHP menolak class dengan fatal error sejak awal.
PHP 8.4 — Property Hooks dan Ergonomi Baru #
PHP 8.4 menyapu bersih boilerplate yang tersisa. Property hooks memindahkan logika getter/setter langsung ke property, sementara asymmetric visibility memisahkan hak baca dan hak tulis — misalnya baca public tetapi tulis private. Kata kunci new pada nilai default parameter tidak lagi memerlukan tanda kurung, keluarga mb_trim() menghadirkan pemangkasan teks yang sadar Unicode, dan array_find()/array_any()/array_all() mengisi celah lama pada operasi array. Lazy objects menutup daftar sebagai fondasi inisialisasi objek yang ditunda.
<?php
class NamaProduk
{
public string $nilai {
set (string $nilai) {
$this->nilai = trim($nilai);
}
}
public function __construct(string $nilai)
{
$this->nilai = $nilai;
}
}
$produk = new NamaProduk(" Kopi Toraja ");
echo "[" . $produk->nilai . "]\n";
$stok = [
["nama" => "Kopi Gayo", "sisa" => 0],
["nama" => "Teh Melati", "sisa" => 12],
];
$tersedia = array_find($stok, fn(array $item): bool => $item["sisa"] > 0);
echo "Tersedia: " . $tersedia["nama"] . "\n";
var_dump(array_any($stok, fn(array $item): bool => $item["sisa"] === 0));
var_dump(array_all($stok, fn(array $item): bool => $item["sisa"] > 0));
$label = "\u{00A0}Kopi Gayo\u{00A0}";
var_dump(trim($label) === "Kopi Gayo");
var_dump(mb_trim($label) === "Kopi Gayo");Output yang Dihasilkan:
[Kopi Toraja]
Tersedia: Teh Melati
bool(true)
bool(false)
bool(false)
bool(true)Perhatikan empat fitur pada contoh tersebut:
- Property hook — setiap penugasan ke
$produk->nilaimelewati hooksetyang memangkas spasi; akses baca tetap terlihat seperti property biasa dari luar class. array_find()— mengembalikan elemen pertama yang lolos callback (bukan boolean), ataunullbila tidak ada yang lolos.array_any()danarray_all()— menjawab pertanyaan “ada sekurang-kurangnya satu yang lolos” dan “semua lolos” dalam satu panggilan, tanpa loop manual.mb_trim()— NBSP (\u{00A0}, non-breaking space) bukan spasi ASCII sehinggatrim()membiarkannya menempel;mb_trim()mengenalinya sebagai whitespace Unicode dan membuangnya.
Ergonomi kecil juga ikut menumpuk. Sejak PHP 8.4, new pada nilai default parameter boleh ditulis tanpa tanda kurung:
<?php
class Penanda
{
public function label(): string
{
return "penanda";
}
}
// PHP 8.4: "new" tanpa tanda kurung pada nilai default parameter
function ambilLabel(Penanda $penanda = new Penanda): string
{
return $penanda->label();
}
echo ambilLabel() . "\n";Output yang Dihasilkan:
penandaNilai default $penanda = new Penanda membangun objek segar setiap kali argumen tidak diisi — sebelum PHP 8.4, penulisan seperti ini wajib memakai tanda kurung new Penanda(). Bedah lengkap fitur visualisasi tingkat lanjutnya ada di chapter Property Hooks
dan Asymmetric Visibility
.
Referensi #
- Fitur baru PHP 8.4 — php.net
— halaman serupa tersedia untuk versi lain: ganti
migration84menjadimigration83,migration82,migration81, ataumigration80. - Versi PHP yang didukung — php.net
- Enumerations — php.net
- Property Hooks — php.net
Ringkasan #
PHP 8.0 meletakkan fondasi sintaks modern lewat named arguments, match, nullsafe, dan union types; 8.1 membawa enum dan readonly; 8.2 merapikan keduanya sekaligus memperkaya jenis tipe; 8.3 menambah ketelitian lewat json_validate() dan #[\Override]; dan 8.4 menyapu boilerplate dengan property hooks serta koleksi fungsi baru. Dengan peta ini, Anda bisa membaca kode modern mana pun dan tahu fitur apa yang sedang dipakai beserta versi minimum yang diminta. Peta ini juga menimbulkan pertanyaan praktis: bagaimana jika server produksi Anda belum semuanya berjalan di 8.4? Chapter berikutnya menjawabnya dengan teknik menjaga kompatibilitas antar versi.