Site icon SUSANTOKUN

Property Hooks PHP 8.4: Ganti Getter-Setter Lebih Rapi

Property hooks PHP 8.4 adalah cara baru membungkus akses properti: logika baca dan tulis ditempel langsung ke deklarasi properti, bukan lagi di method getNama() dan setNama(). Fitur ini resmi masuk sejak PHP 8.4.0 dirilis 21 November 2024 dan kini jadi bagian normal PHP 8.5. Kalau codebase kamu masih bergaya getter-setter klasik, hooks membuat class lebih pendek tanpa mengubah cara pemanggilan dari luar. Yang penting dipahami: hooks bukan sekadar gula sintaks; ada aturan backed versus virtual, inheritance, dan beberapa jebakan.

Apa Itu Property Hooks PHP 8.4

Property hooks adalah mekanisme untuk mencegat operasi baca (get) dan tulis (set) pada sebuah properti. Hooks hanya tersedia untuk properti non-static, baik yang bertipe maupun yang tidak bertipe. Tujuannya dua: memakai properti secara langsung tanpa method pembungkus, dan membuat properti yang nilainya tidak disimpan sama sekali.

Dari situ muncul dua istilah yang wajib dibedakan:

Cara membedakannya: kalau hook merujuk $this->namaProperti, berarti backed; kalau hanya membaca properti lain, berarti virtual. Satu catatan penting: property hooks tidak kompatibel dengan properti readonly. Untuk membatasi siapa yang boleh menulis, pakai asymmetric visibility.

Sintaks Dasar: get, set, dan $value

Perubahan paling kelihatan: tanda titik koma. Properti yang punya hook diakhiri blok {}, bukan ;. Di dalamnya boleh ada satu atau dua hook, dan urutan penulisannya tidak berpengaruh.

<?php
class Produk
{
    public string $nama = '' {
        set => trim($value);
    }

    public string $slug {
        get => strtolower(str_replace(' ', '-', $this->nama));
    }
}

$p = new Produk();
$p->nama = '  Kopi Gayo  ';
echo $p->nama; // Kopi Gayo
echo $p->slug; // kopi-gayo

Pada contoh di atas, hook set ditulis sebagai arrow expression. Nilai hasil ekspresi itulah yang disimpan ke backing value, jadi trim() otomatis berlaku setiap kali ada yang menulis ke $nama. Parameter tidak perlu ditulis karena tipenya sama dengan properti; PHP memberi nama $value secara otomatis.

Kalau butuh beberapa baris, ganti arrow dengan blok biasa. Di bentuk blok, hook set bertanggung jawab menulis sendiri ke properti, jadi validasi dan penulisan nilai dilakukan manual di dalam kurung kurawal. Tipe parameter boleh lebih lebar (contravariant) dari tipe properti, misalnya set(string|Stringable $value) untuk properti string; yang tidak boleh adalah tipe yang tidak berhubungan seperti array.

Virtual Property untuk Nilai Turunan

Kasus paling rapi untuk virtual property adalah nilai yang sebenarnya hasil hitungan. Dulu pola ini menuntut method getLuas() plus docblock supaya IDE paham. Sekarang cukup satu hook get, dan properti tetap terlihat seperti data biasa.

<?php
class PersegiPanjang
{
    public function __construct(
        public int $panjang,
        public int $lebar,
    ) {}

    public int $luas {
        get => $this->panjang * $this->lebar;
    }
}

$kotak = new PersegiPanjang(4, 5);
echo $kotak->luas; // 20
$kotak->luas = 30; // Error: tidak ada operasi set

Karena tidak ada hook set, properti $luas hanya bisa dibaca. Upaya menulis ke sana akan melempar error, bukan diam-diam diabaikan. Inilah bedanya dengan __get() ajaib yang bisa menelan kesalahan tanpa jejak.

Bedanya dengan Getter-Setter Klasik

Secara fungsi, hook get/set meniru pasangan method yang selama ini kita tulis manual. Bedanya ada di tiga hal:

Risikonya psikologis: karena terlihat seperti properti biasa, orang bisa menaruh operasi mahal di dalam hook. Baca fitur baru PHP 8.5 untuk melihat arah bahasa ini bergerak, lalu tentukan batas wajar antara hook dan method.

Asymmetric Visibility: public private(set)

Hooks mengatur perilaku, sedangkan asymmetric visibility mengatur hak akses. Keduanya diperkenalkan di versi yang sama dan sering dipakai berpasangan. Sintaksnya menaruh modifier kedua untuk operasi tulis, sehingga siapa pun boleh membaca properti tapi hanya kode di dalam class yang boleh menulisnya.

<?php
class Pengguna
{
    public private(set) string $namaDepan;

    public function __construct(string $namaDepan)
    {
        $this->namaDepan = $namaDepan;
    }
}

Aturan yang perlu diingat, visibilitas get tidak boleh lebih sempit daripada visibilitas set. Pola ini lebih tepat daripada readonly ketika nilainya masih boleh berubah, hanya saja perubahan harus lewat method tertentu.

Interface Boleh Mendeklarasikan Properti

Perubahan yang mudah terlewat: interface kini bisa mendeklarasikan properti, lengkap dengan operasi mana yang diwajibkan. Class yang mengimplementasikan boleh memenuhinya dengan properti biasa maupun dengan hook. Contohnya public string $namaLengkap { get; } mewajibkan properti yang bisa dibaca, dan implementasinya sah memakai hook get berisi penggabungan dua field lain.

Interface tidak boleh mendeklarasikan properti tanpa menentukan hook-nya. Jadi public string $nama; di dalam interface adalah kesalahan sintaks; tulis { get; }, { set; }, atau keduanya. Ini memaksa kontraknya eksplisit, meski sedikit lebih panjang. Kalau kamu baru pindah dari gaya PHP 5, bagian dasar halaman dinamis dengan PHP tetap relevan untuk memahami alur request-nya.

Hook di Class Turunan dan Kata Kunci final

Hook diwarisi seperti method, dan tiap hook bisa ditimpa secara terpisah. Class anak boleh menambah hook pada properti yang di parent-nya polos, dengan syarat nilai default harus dideklarasikan ulang. Kalau ingin mengunci perilaku, tandai hook dengan final, misalnya final set => strtolower($value);. Class turunan masih boleh menambah hook get, tapi tidak boleh mengganti set.

Untuk memanggil implementasi parent secara eksplisit, gunakan parent::$username::get() atau parent::$username::set($value). Tanpa sintaks itu, hook parent diabaikan sepenuhnya. Kebiasaan ini berguna ketika class induk nanti ditambah validasi sendiri.

Jebakan yang Sering Kelewat

Hook juga sebaiknya tetap murah. Kalau di dalam get ada query database atau panggilan HTTP, setiap pembacaan properti jadi operasi jaringan yang tak terlihat di kode. Untuk kasus itu, method eksplisit lebih jujur. Pola serupa penting saat menyusun relasi data, seperti di tutorial relationship table di Laravel.

Cara Mencoba di Project Sendiri

Syaratnya satu: PHP 8.4 atau lebih baru. Cek versi runtime, lalu lint file yang diubah supaya kesalahan sintaks ketahuan sebelum masuk CI.

php -v
php -l src/Produk.php
php -r 'require "src/Produk.php"; $p = new Produk(); $p->nama = "  Kopi Gayo  "; echo $p->slug, PHP_EOL;'

Kalau project masih di 8.2 atau 8.3, hooks belum bisa dipakai dan file gagal di-parse. Untuk library yang dipublikasikan, tambahkan syarat versi di composer.json sebelum memakai fitur ini.

FAQ

Apakah property hooks menggantikan getter dan setter sepenuhnya? Tidak. Hooks cocok untuk validasi, normalisasi, dan nilai turunan; method lebih jelas untuk operasi berat atau yang jadi bagian alur bisnis.

Apakah menambah hook mengubah kode pemanggil? Tidak. Akses tetap $objek->properti, dan selama tipe serta nama properti tidak berubah, kode lama tetap jalan.

Bisa dipakai di properti static? Tidak. Hooks hanya untuk properti non-static. Untuk properti static, tetap pakai method atau pola lama.

Kesimpulan

Property hooks membuat class PHP lebih ringkas tanpa mengorbankan kemampuan menambah aturan nanti. Kuncinya tiga keputusan: tentukan backed atau virtual, pilih hook atau asymmetric visibility, lalu jaga isi hook tetap ringan. Kalau itu dipegang, hooks jadi alat yang rapi; kalau dilewati, kompleksitasnya cuma pindah ke tempat yang lebih sulit dilacak.

Referensi

Exit mobile version