Tutorial OOP Lanjutan
Attribute
Materi ini memiliki 1 buah lampiran. Namun Anda tidak dapat mengakses lampiran karena belum terdaftar di kursus ini. Klik disini untuk mendaftar.
Pada video ini kita akan membahas mengenai Attribute. Attribute adalah fitur yang baru diperkenalkan di PHP versi 8, dan fitur ini sudah digunakan di function bawaan PHP. Sebagai contoh kalau kita lihat function hash_equals dari halaman dokumentasi PHP, ternyata function ini sudah menggunakan Attribute yang bisa kita lihat pada bagian parameternya. Sebagai penanda Attribute, kita menggunakan simbol # (kres atau yang di sosial media lebih dikenal dengan nama hashtag) diikuti oleh tanda kurung siku dan nama Attribute-nya.
Dengan menggunakan Attribute, maka kita bisa menambahkan metadata pada parameter. Biasanya nama attribute-nya memberikan makna tambahan mengenai parameter yang bersangkutan. Sebagai contoh, function hash_equals memiliki parameter dengan attribute SensitiveParameter. Artinya parameter yang bersangkutan bersifat sensitif. Kita harus lebih berhati-hati dalam menjaga nilai yang digunakan sebagai parameter.
Ini adalah cara deklarasi Attribute. Caranya tetap sama dengan cara deklarasi class, namun pada bagian depannya kita tambahkan #[Attribute]. Artinya kelas yang kita deklarasikan ini akan digunakan sebagai Attribute. Sebagai contoh disini kita membuat attribute NotNull.
Kemudian untuk menggunakan attribute tersebut, kita tinggal tambahkan tanda kres dan tanda kurung siku. Di dalamnya kita sebutkan nama kelas attribute kita. Attribute dapat digunakan pada banyak tempat. Bisa pada kelas, bisa pada method, property, ataupun parameter. Pada contoh disini kita menggunakan attribute pada property.
Kita bisa menambahkan banyak attribute sekaligus pada property yang sama. Sebagai contoh disini kita menambahkan attribute NotNull yang baru saja kita deklarasikan. Kemudian kita juga menambahkan attribute StringLength. Dan kalau kita perhatikan lagi, attribute StringLength ini memiliki nilai. Sebagai contoh pada property $id, attribute StringLength memiliki nilai min 4 dan nilai max 8. Sedangkan pada property $password, attribute StringLength memiliki nilai min 8 dan max 16.
Bagaimana cara membuat attribute yang bisa menyimpan nilai? Nah, caranya sama seperti membuat kelas tadi ya. Kita gunakan #[Attribute] ditambahkan dengan kelas. Namun di dalam kelas, kita tambahkan constructor untuk menyimpan nilai parameter sebagai property. Berhubung PHP 8 sudah memiliki fitur constructor promotion, jadi kita tinggal tambahkan kata public pada setiap parameter dan parameter otomatis diangkat menjadi property.
Pada contoh sebelumnya, kita menggunakan attribute pada property ya. Nantinya kita bisa mengambil attribute apa saja yang dikandung oleh property, dengan cara memanggil method getAttributes pada ReflectionProperty. Jadi kita akan menyambung dengan praktikum dari video sebelumnya, yang membahas mengenai Reflection dan ValidationUtility.
Agar lebih jelas, kita langsung coba praktek. Kita lanjutkan kode dari video sebelumnya. Pertama kita coba untuk membuat Attribute terlebih dahulu. Kita tambahkan file baru pada folder data, dengan nama Attribute.php. Di dalamnya kita deklarasikan attribute. Bagaimana caranya? Kita sudah belajar caranya barusan ya. Pertama kita tulis dahulu kata kuncinya yaitu #[Attribute] dan diikuti oleh deklarasi kelas, yaitu class NotNull{}. Berhubung kelas ini kosong jadi kita hanya beri kurung kurawal saja.
Sekalian kita buat attribute kedua ya. Kita ketik lagi #[Attribute] class StringLength{}. Untuk saat ini attribute StringLength belum kita beri nilai. Jadi kita hanya membuat kelas kosong saja.
Selanjutnya kita buka file LoginData.php. Pertama kita hubungkan dahulu ke file Attribute.php. Kita panggil fungsi require_once. Nah, berhubung file Attribute.php berada pada folder yang sama dengan file LoginData.php, sedangkan script yang akan menggunakan LoginData.php ini mungkin saja berada pada folder yang berbeda. Maka ada baiknya kita menggunakan __dir__. Jadi kita akan merujuk ke file Attribute.php berdasarkan folder dari script sekarang. Kita tambahkan tanda titik, dan string ‘/Attribute.php’.
Nah, sekarang kita sudah bisa menambahkan attribute pada property. Sebagai contoh, pada property #id, kita tambahkan attribute #[NotNull]. Kita simpan dan coba jalankan php data/LoginData.php. Script berjalan dengan baik namun tidak ada hasil ya.
Kita bisa menambahkan beberapa attribute sekaligus pada property yang sama. Sebagai contoh pada property $id, kita tambahkan lagi attribute #[StringLength]. Kalau dijalankan juga tidak ada error ya.
Nah, untuk saat ini deklarasi Attribute masih belum diwajibkan. Artinya kita juga bisa menambahkan attribute baru walaupun belum pernah kita deklarasikan. Sebagai contoh, kita tambahkan lagi attribute #[NotInteger]. Kalau dijalakan juga tidak error ya. Namun walaupun deklarasi tidak diwajibkan, kita tetap disarankan untuk tetap melakukan deklarasi. Kita hapus dahulu attribute #[NotInteger].
Bagaimana cara melihat attribute apa saja yang dimiliki oleh property? Untuk melakukan hal ini, kita buka file ValidationUtility.php. Kita lihat ke method validate. Pertama kita komentari dahulu kode yang bisa melempar error. Kita tambahkan kode echo “Property $name\n”. Kita simpan dan jalankan validation.php. Kita mendapatkan hasil Property id, Property password dan Validation succeeds.
Selanjutnya kita akan mengambil attribute apa saja yang dimiliki oleh setiap property. Kita tulis kodenya yaitu $attributes = $property->getAttributes(). Kemudian kita coba var_dump nilai $attributes. Kita simpan dan lihat hasilnya.
Nah, kita bisa melihat pada property $id terdapat 2 buah attribute ya. Sedangkan pada property $password tidak ada attribute sama sekali. Namun kita masih belum bisa melihat nama attribute-nya. Kalau misalkan kita ingin mencetak apa saja nama attribute, maka kita harus melakukan perulangan foreach($attributes as $attribute). Di dalamnya kita echo “Attribute {$attribute->getName()}\n”.
Kita simpan dan jalankan. Dan sekarang kita bisa melihat bahwa di dalam property $id terdapat attribute NotNull dan StringLength.
Kalau misalkan kita hanya ingin mengambil attribute tertentu saja, maka kita bisa menambahkan argument pada method getAttributes. Misalkan kita hanya ingin mengambil attribute NotNull saja, maka kita tambahkan argument seperti ini. NotNull::class. Kalau kita jalankan, maka sekarang property $id hanya memiliki 1 attribute saja, yaitu NotNull. Karena pada saat mengambil attribute, kita melakukan filter hanya mengambil attribute NotNull saja. Yang perlu diingat disini adalah walaupun hasilnya hanya 1, yang dikembalikan tetap dalam bentuk array ya. Jadi untuk mengakses attribute-nya, kita harus menggunakan foreach atau index. Kita kosongkan kembali argument.
Kita ubah kode di dalam foreach $attributes. Pertama kita simpan dahulu namanya sebagai variable sementara. Namun perhatikan kalau disini kita menggunakan variable $name, sementara diluar foreach sudah ada variable $name juga, nantinya malah berpotensi menyebabkan bugs. Oleh karena itu kita perjelas dahulu variable $name yang dimaksud untuk menyimpan nama apa.
Variable $name yang diatas ini adalah nama property. Oleh karena itu lebih baik namanya kita ubah menjadi $propertyName. Kita ubah jadi parameter echo yang memanggil variable $propertyName.
Sedangkan yang berada di dalam foreach $attributes adalah nama Attribute. Oleh karena itu kita gunakan nama variable $attributeName = $attribute->getName(). Kemudian kita periksa, apabila nama attribute-nya adalah ‘NotNull’, maka kita panggil method validateNotNull($object, $property).
Kita buat method baru dengan nama validateNotNull, dengan dua buah parameter Object $object dan ReflectionProperty $property. Di dalamnya pertama kita buat dahulu variable $propertyName yang nilainya diambil dari $property->name.
Setelah itu kita copy paste kode yang kita komentari sebelumnya. Kita pindahkan ke method baru, dan kita uncomment. Perhatikan di dalam throw kita menggunakan variable $name ya, yang mana sekarang nama variablenya sudah kita ubah menjadi $propertyName. Jadi kita mesti ganti isi kedua throw-nya agar tidak error.
Jadi sekarang kita hanya melakukan validasi kosong hanya pada property yang mengandung attribute NotNull saja. Dimana pada saat ini hanya property $id saja. Jadi kalau kita buka kembali kode pada validation.php. Kita ubah property $id menjadi komentar. Maka kita mendapatkan error bahwa property $id belum diinisialisasi. Namun kalau misalkan property $password yang kita ubah menjadi komentar, maka tidak terjadi error, karena kita tidak menjalakan method validateNotNull. Dengan menggunakan Attribute, kita bisa lebih flexible menentukan property mana yang mesti divalidasi, dan property mana yang tidak perlu divalidasi.
Kita lanjutkan ke validasi yang lebih rumit. Kita akan menambahkan property StringLength untuk menentukan validasi terhadap panjang string, agar tidak lebih kecil dari nilai min dan tidak lebih besar dari nilai max.
Untuk melakukan hal tersebut, pertama kita kembali ke file Attribute.php terlebih dahulu. Pada deklarasi attribute, kita harus membuat kelas yang bisa menyimpan nilai min dan max. Jadi pada kelas StringLength, kita tambahkan constructor dengan parameter public int $min dan public int $max.
Kemudian kita buka file LoginData.php. Pada saat menggunakan Attribute StringLength, kita harus memberikan nilai untuk min dan max. Cara menambahkan nilainya adalah setelah nama Attribute StringLength, kita tambahkan tanda kurung. Di dalamnya kita tuliskan nilai dalam bentuk pasangan key: value, dipisahkan dengan tanda koma. Jadi nilainya adalah min:4, max:8.
Lalu pada file ValidationUtility, kita mesti melakukan validasi StringLength. Pertama kita tambahkan dahulu percabangan else if $attributeName == ‘StringLength’. Maka kita panggil method baru validateStringLength. Argument-nya sama dengan validateNotNull, namun kita tambahkan satu argument lagi yaitu $attribute.
Kita copy paste method validateNotNull. Kita ubah menjadi validateStringLength. Namun kita mesti menambahkan argument terakhir ReflectionAttribute $attribute. Di dalamnya ada validasi not null ya, namun disini kita tidak melempar error, melainkan langsung return saja.
Bagaimana cara mengambil nilai min dan max pada attribute? Disini kita bisa menggunakan method newInstance. Sebagai contoh, kita buat dahulu variable penampungnya dengan nama $attributeInstance untuk menampung hasil dari $attribute->newInstance(). Pertama kita var_dump dahulu nilai $attributeInstance.
Kita jalankan. Dan kita bisa melihat bahwa kita mendapatkan sebuah object yang terbuat dari kelas StringLength. Di dalamnya ada property $min dan $max. Jadi kita bisa mengakses nilai attribute dari object ini.
Pertama kita cek dahulu apabila panjang string lebih kecil dari $min. Caranya adalah:
if(strlen($value) < $attributeInstance->min){ throw new Exception("Error: {$propertyName}'s length is less than {$attributeInstance->min}"); }
Kemudian kita copy paste kode-nya untuk memeriksa apakah lebih besar dari max. Kita ubah operator perbandingannya menjadi lebih besar, dan nama property-nya menjadi max. Kata less kita ubah menjadi more. Dan kita ubah lagi nama property min menjadi max.
Kita simpan dan jalankan. Saat ini validasi berhasil berjalan ya. Namun kalau kita ubah nilai pada $id menjadi ‘adm’, maka kita mendapatkan error karena panjangnya lebih kecil dari 4. Sedangkan kalau kita ganti nilainya menjadi adminbarumasuk, maka kita mendapatkan error karena panjangnya lebih besar dari 8.
Jadi pada video ini kita sudah belajar mengenai Attribute, dan bagaimana cara menggunakannya untuk menambahkan metadata pada property. Nantinya metadata ini akan kita gunakan lagi untuk menentukan metode validasi apa saja yang perlu kita jalankan pada property yang bersangkutan. Kalau dibandingkan dengan validasi pada video sebelumnya, semua property divalidasi tidak boleh kosong. Sedangkan pada video ini, kita hanya melakukan validasi pada property yang memiliki attribute saja, sehingga penggunaan ValidationUtility menjadi lebih flexible.
Dengan menggunakan fasilitas tanya jawab, maka Anda bisa bertanya dan akan dijawab langsung oleh instruktur kursus.
Anda belum terdaftar pada kursus ini sehingga tidak bisa mengajukan pertanyaan.