Topik ini membahas enum, yaitu tipe data yang nilai sahnya terbatas pada sekumpulan pilihan yang ditetapkan penulis kode. Pembahasan mencakup enum murni tanpa nilai, backed enum yang setiap casenya membawa nilai string atau int, serta metode dan fungsi statis yang dapat dilekatkan pada enum. Contoh yang dipakai berputar pada status pesanan arsip dan level keanggotaan perpustakaan. Setelah membacanya, pilihan status yang sebelumnya ditulis sebagai konstanta kelas atau string lepas dapat ditingkatkan menjadi enum yang diperiksa oleh bahasa.
Enum murni#
Enum dideklarasikan dengan kata kunci enum, dan setiap pilihan nilai di dalamnya disebut case. Enum murni (pure enum) tidak membawa nilai apa pun, sehingga deklarasinya hanya memuat daftar nama case. Setiap case diwakili satu objek tunggal dari kelas enum tersebut, sehingga dua pemanggilan StatusArsip::Diproses menghasilkan objek yang persis sama dan perbandingan === berjalan sebagaimana mestinya.
<?php
declare(strict_types=1);
enum StatusArsip
{
case Baru;
case Diproses;
case Selesai;
case Ditolak;
}
$pesanan = StatusArsip::Diproses;
if ($pesanan === StatusArsip::Diproses) {
echo "Pesanan masih diproses", PHP_EOL;
}
foreach (StatusArsip::cases() as $status) {
echo $status->name, PHP_EOL;
}Pesanan masih diproses
Baru
Diproses
Selesai
DitolakMethod cases() mengembalikan seluruh case dalam urutan deklarasinya, sehingga daftar tersebut dapat diulang untuk menampilkan menu pilihan atau mengisi pemeriksaan secara otomatis. Nama setiap case dapat dibaca melalui properti name. Karena tipe StatusArsip kini menjadi tipe data sungguhan, parameter fungsi dapat dituliskan StatusArsip $status, dan nilai di luar empat case tersebut ditolak sebelum fungsi dijalankan.
Backed enum#
Backed enum adalah enum yang setiap casenya dibekali satu nilai skalar, yaitu string atau int, dengan menuliskan tipe backing setelah nama enum. Nilai tersebut dibaca melalui properti value dan digunakan ketika case perlu disimpan ke basis data atau dikirim melalui API, sedangkan nama case tetap menjadi identitasnya di dalam kode. Diagram berikut memperlihatkan pemetaan nama case ke nilai backing pada enum level keanggotaan perpustakaan.
Konversi dua arah disediakan oleh bahasa. Method from() menerima nilai backing dan mengembalikan case yang cocok, sedangkan tryFrom() melakukan hal yang sama tetapi mengembalikan null apabila tidak ada yang cocok. Kedua method ini bersifat statis dan dipanggil langsung pada kelas enum, sebagaimana contoh berikut.
<?php
declare(strict_types=1);
enum LevelKeanggotaan: string
{
case Umum = 'umum';
case Pelajar = 'pelajar';
case Peneliti = 'peneliti';
}
$level = LevelKeanggotaan::Pelajar;
echo $level->name, PHP_EOL;
echo $level->value, PHP_EOL;
echo LevelKeanggotaan::from('peneliti')->name, PHP_EOL;
$tidakDikenal = LevelKeanggotaan::tryFrom('korporat');
var_dump($tidakDikenal);
try {
LevelKeanggotaan::from('korporat');
} catch (ValueError $e) {
echo 'Error: ', $e->getMessage(), PHP_EOL;
}Pelajar
pelajar
Peneliti
NULL
Error: "korporat" is not a valid backing value for enum LevelKeanggotaanPemanggilan from() dengan nilai yang tidak terdaftar melempar exception ValueError, sedangkan tryFrom() mengembalikan null tanpa melempar apa pun. Tipe nilai backing, baik string maupun int, dinyatakan satu kali pada deklarasi enum, dan seluruh case wajib memakai tipe yang sama.
Metode dan fungsi statis pada enum#
Enum adalah kelas lengkap, sehingga enum dapat memiliki metode, metode statis, dan konstanta, serta boleh mengimplementasikan interface. Di dalam metode, $this merujuk pada case tempat metode itu dipanggil. Pola yang lazim adalah memakai ekspresi match terhadap $this untuk menghasilkan label, dan fungsi statis untuk menyediakan cara pembuatan case yang lebih ramah daripada from().
<?php
declare(strict_types=1);
enum LevelKeanggotaan: string
{
case Umum = 'umum';
case Pelajar = 'pelajar';
case Peneliti = 'peneliti';
public function label(): string
{
return match ($this) {
self::Umum => 'Anggota umum',
self::Pelajar => 'Anggota pelajar',
self::Peneliti => 'Anggota peneliti',
};
}
public static function dariKode(string $kode): static
{
return self::tryFrom($kode) ?? self::Umum;
}
}
$level = LevelKeanggotaan::dariKode('pelajar');
echo $level->label(), PHP_EOL;
echo LevelKeanggotaan::dariKode('korporat')->label(), PHP_EOL;Anggota pelajar
Anggota umumMethod dariKode() menampung kebijakan nilai bawaan di satu tempat, yaitu aturan bahwa kode yang tidak dikenal jatuh ke case Umum. Dengan begitu, pemanggil di seluruh proyek tidak perlu mengulang logika tryFrom() tersebut. Pemilihan static sebagai tipe kembalian membuat metode tetap benar apabila enum diwariskan. Label yang dihasilkan label() bersifat tampilan, sehingga perubahan kata pada label tidak menyentuh nilai backing yang tersimpan di basis data.
Kesalahan umum#
Kesalahan kedua adalah menganggap enum sebagai kelas biasa yang dapat diinstansiasi. Pernyataan new StatusArsip() melempar Error dengan pesan Cannot instantiate enum StatusArsip, karena satu-satunya cara memperoleh case adalah melalui StatusArsip::NamaCase, cases(), atau from(). Penulisan case baru pada saat program berjalan juga tidak dimungkinkan, dan itulah tujuan enum.
Kesalahan ketiga terjadi pada saat penulisan backed enum itu sendiri. Seluruh case wajib membawa nilai dengan tipe yang sama dengan deklarasi, dan nilainya tidak boleh kembar. Enum yang satu casenya bernilai sementara case lainnya tidak, atau yang memiliki dua case dengan nilai string identik, gagal dimuat sejak proses kompilasi. Pemeriksaan ini memang terjadi lebih dahulu, sehingga kesalahan semacam itu tidak pernah sampai ke tahap eksekusi.
Ringkasan#
- Enum membatasi nilai sah pada sekumpulan case yang dideklarasikan, dan setiap case adalah objek tunggal yang dapat dibandingkan dengan
===. - Enum murni tidak membawa nilai, sedangkan backed enum membawa satu nilai string atau int per case yang dibaca melalui
value. from()mengembalikan case dari nilai backing atau melempar ValueError, sedangkantryFrom()mengembalikannull.- Enum dapat memiliki metode dan fungsi statis, sehingga perilaku seperti label dan nilai bawaan ditempatkan di dalam enum itu sendiri.
Referensi#
- Enumerations — PHP Manual — Dokumentasi resmi enum beserta aturan deklarasi case dan pembatasannya.
- Backed enumerations — PHP Manual
— Dokumentasi backed enum serta perilaku
from()dantryFrom(). - Enumeration methods — PHP Manual — Dokumentasi metode, metode statis, dan konstanta pada enum.
- Value listing — PHP Manual
— Dokumentasi method
cases()untuk mengambil seluruh case. - ValueError — PHP Manual
— Dokumentasi kelas exception yang dilempar
from()untuk nilai backing yang tidak terdaftar.