Enum PHP (PHP 8.1+) mendefinisikan tipe dengan sekumpulan nilai yang tetap, yaitu case-nya: enum Status { case Active; case Banned; }. Kamu memakai sebuah case sebagai Status::Active, dan parameter bertipe Status tidak menerima apa pun selain itu. Backed enum, enum Status: string, juga memberi setiap case sebuah nilai yang bisa kamu simpan dan ubah kembali dengan Status::from().
Sebelum ada enum, hal yang sama ditulis sebagai daftar konstanta string, dan tidak ada yang mencegah salah ketik seperti 'actve' sampai ke database. Dengan Status sebagai tipe parameter, hanya ketiga case itu yang bisa dikirim.
Pure enum dan backed enum
Case pada pure enum hanya berupa nama. Backed enum mendeklarasikan tipe setelah namanya, int atau string, dan setiap case lalu wajib punya nilai unik bertipe itu. Setiap case punya ->name; hanya case backed yang punya ->value.
Pilih backed enum setiap kali nilainya keluar dari program: kolom database, URL, field formulir, JSON. Pilih pure enum untuk nilai yang hanya ada di dalam kode, misalnya state sebuah parser.
Mengonversi nilai dengan from() dan tryFrom()
Backed enum mendapat dua static method untuk mengubah nilai yang tersimpan kembali menjadi case. from() melempar ValueError untuk nilai yang tidak dikenal; tryFrom() mengembalikan null, yang cocok dipasangkan dengan ?? untuk nilai bawaan:
Pakai tryFrom() untuk apa pun yang dikirim pengguna, dan from() untuk nilai yang ditulis kodemu sendiri, saat nilai yang tidak dikenal berarti ada bug yang ingin kamu ketahui. Argumennya mengikuti aturan tipe parameter yang biasa: pada enum int, Priority::from('5') mengembalikan Priority::Normal dalam mode bawaan karena '5' dikonversi menjadi 5 lebih dulu, Priority::from('5x') menghasilkan TypeError, dan di bawah declare(strict_types=1) string apa pun menghasilkan TypeError. Itu berlaku juga untuk tryFrom(): Priority::tryFrom('abc') melempar error alih-alih mengembalikan null, jadi periksa dulu input formulir untuk enum int dengan filter_var($raw, FILTER_VALIDATE_INT).
Menampilkan semua case dengan cases()
Enum::cases() mengembalikan array berisi setiap case, sesuai urutan deklarasinya. Begitulah cara membuat dropdown, memvalidasi sebuah list, atau mengambil semua nilai dengan array_column:
Jalankan, pilih sebuah paket, lalu tekan Choose: script yang sama berjalan lagi dengan $_POST['plan'] yang sudah terisi, dan tryFrom() mengubah string yang dikirim kembali menjadi case Plan. Nilai palsu seperti plan=gold menghasilkan null, dan tidak ada opsi yang terpilih.
Method, konstanta, dan interface pada enum
Enum bisa punya method, static method, dan konstanta, serta bisa mengimplementasikan interface. Di dalam method, $this adalah case yang sedang dipakai, sehingga match ($this) menjadi cara alami untuk menempelkan data ke setiap case. Yang tidak bisa dimiliki enum adalah property: data per case berasal dari method.
Enum di dalam match
match membandingkan dengan ===, dan sebuah case enum hanya identik dengan dirinya sendiri, jadi match dan enum sangat cocok. Kalau kamu lupa sebuah case dan case itu sampai ke match, PHP melempar UnhandledMatchError alih-alih diam-diam tidak mengembalikan apa-apa:
Lihat match untuk mengetahui bedanya match dengan switch.
Enum di JSON dan sebagai string
json_encode() menulis case backed sebagai nilainya. Pure enum tidak bisa di-encode, dan echo pada case mana pun akan gagal, karena enum adalah objek, bukan string. Cetak ->value atau ->name sebagai gantinya:
echo Role::Admin; melempar Error ("Object of class Role could not be converted to string"), dan enum tidak bisa mengimplementasikan __toString(). Saat data masuk kembali, JSON memberikan string biasa, jadi konversi dengan from() atau tryFrom() seperti contoh tadi. Selengkapnya tentang encoding ada di json_encode.
Kesalahan umum pada enum
Tiga error ini muncul berulang kali. Sebuah case tidak pernah sama dengan nilainya, case tidak bisa menjadi key array, dan new tidak bisa dipakai pada enum:
Kalau kamu butuh map dengan key berupa case itu sendiri, pakai SplObjectStorage atau WeakMap, yang menerima objek sebagai key.
Pertanyaan yang sering diajukan
Bagaimana cara mendapatkan nilai dari enum di PHP?
Pada backed enum, baca ->value: Status::Active->value bernilai 'active'. Setiap case juga punya ->name, yaitu nama case dalam bentuk string ('Active'). Pure enum (tanpa : string atau : int) hanya punya ->name.
Apa bedanya from() dan tryFrom() pada enum PHP?
Keduanya mengubah sebuah nilai menjadi case dari backed enum. Status::from('active') mengembalikan case-nya atau melempar ValueError kalau tidak ada case dengan nilai itu; Status::tryFrom('nope') justru mengembalikan null. Pakai tryFrom() untuk input pengguna dan from() saat nilai yang salah berarti ada bug.
Bagaimana cara mendapatkan semua nilai enum di PHP?
Status::cases() mengembalikan setiap case sesuai urutan deklarasinya. Untuk nilai-nilai backed enum, pakai array_column(Status::cases(), 'value'), dan untuk nama-namanya array_column(Status::cases(), 'name').
Apa bedanya pure enum dan backed enum?
Case pada pure enum (enum Suit { case Hearts; }) hanya berupa nama. Backed enum (enum Suit: string { case Hearts = 'H'; }) memberi setiap case nilai int atau string yang unik, yang kamu butuhkan untuk menyimpannya di database, menaruhnya di formulir atau JSON, dan mengubahnya kembali dengan from() atau tryFrom().
Apakah enum PHP bisa punya method?
Bisa. Enum bisa punya method, static method, dan konstanta, serta bisa mengimplementasikan interface. Di dalam method, $this adalah case yang sedang dipakai, jadi return match ($this) { self::Active => 'green', self::Banned => 'red' }; adalah pola yang umum. Enum tidak bisa punya property.