PHP memiliki sekumpulan API refleksi yang dapat digunakan untuk mengintrospeksi kelas, antarmuka, fungsi, metode, dan ekstensi. Di antara banyak fitur lainnya, refleksi memungkinkan kita untuk mengakses properti kelas dan memanggil metode kelas meskipun dideklarasikan sebagai pribadi/dilindungi. Saya banyak menggunakannya untuk menulis pengujian unit untuk metode privat di beberapa proyek lawas di mana pengujian metode publik terlalu rumit Show Jadi, bagaimana cara melakukannya? class Foo { private $bar = 'a'; protected function call() { return 'bazz'; } } $obj = new Foo; // lets create reflection for private $bar property $reflectedProperty = new ReflectionProperty(Foo::class, 'bar'); // set it as accessible $reflectedProperty->setAccessible(true); // now we can read the value of the property echo ($reflectedProperty)->getValue($obj); // now reflection for protected call() method $reflectedMethod = new ReflectionMethod(Foo::class, 'call'); // set it as accessible $reflectedMethod->setAccessible(true); // now we can invoke/call that method as if it is public method echo $reflectedMethod->invoke($obj); Seperti yang dapat kita lihat, untuk mengakses properti atau metode pribadi/dilindungi, kita perlu memanggil metode setAccessible(true) sebelum mengakses. Jika kami tidak memanggil metode ini, kami akan mendapatkan pengecualian Uncaught ReflectionException: Trying to invoke protected method Foo::call() from scope ReflectionMethod_ Agak mengganggu karena jika kita menerima objek ReflectionProperty atau ReflectionMethod dari pustaka atau modul pihak ketiga mana pun, kita tidak tahu apakah setAccessible() telah dipanggil pada objek itu atau tidak. Jadi agar lebih aman, kita perlu memanggil setAccessible() lagi PHP 8. 1 memecahkan masalah itu Mulai sekarang, kita dapat mengakses properti atau memanggil metode melalui API refleksi tanpa perlu memanggil setAccessible() secara eksplisit, meskipun dilindungi/pribadi Setiap kali kami mencoba mengakses properti pribadi/dilindungi atau memanggil metode, itu akan berperilaku seolah-olah setAccessible(true) telah dipanggil di muka Saya sedang mendiskusikan teknik ini selama tinjauan kode baru-baru ini, dan saya menyadari teknik keren ini mungkin tidak begitu dikenal. Saya menemukannya secara tidak sengaja beberapa tahun yang lalu Kadang-kadang, semata-mata untuk tujuan pengujian, kita mungkin perlu mengakses properti atau metode pribadi atau yang dilindungi. Kecenderungan kita yang biasa adalah menggunakan Refleksi untuk melakukan ini. Refleksi agak rumit, karena ada banyak boilerplate tambahan untuk menyiapkannya Tapi penutupan sebenarnya memberi kita cara keren untuk melakukannya dengan lebih mudah. Jika Anda pernah menggunakan metode 4 JavaScript, kita dapat melakukan hal yang sama di PHPMari kita mulai dengan kelas sampel
Masuk ke mode layar penuh Keluar dari mode layar penuh Properti non-statisKami tahu cara membaca dan mengubah 5. Ini publik, jadi tidak ada masalah di sanaSekarang, bagaimana jika kita perlu, di suatu tempat dalam ujian, untuk menetapkan usia yang tepat. Itu adalah properti yang dilindungi, jadi kita tidak bisa langsung mengubahnya, tetapi Penutupan bisa memberi kita jalan keluarnya
Masuk ke mode layar penuh Keluar dari mode layar penuh Jadi, apa yang kita lakukan di sini? _Masuk ke mode layar penuh Keluar dari mode layar penuh Pertama, kami membuat penutupan yang mengubah 6 menjadi apa pun yang diteruskan ke sana. Jika kami mencoba melakukan _7, kami akan mendapatkan kesalahan, karena kami mendefinisikan ini di luar kelas. 8 sebenarnya tidak ada di sini, atau, jika kita memasukkan kode ini ke dalam pengujian unit, 8 akan merujuk ke kelas pengujian unit itu sendiriDi situlah _0 masuk. 1 mengikat penutupan ke objek baru, dan memanggilnya dengan argumen apa pun yang Anda berikan padanya. Dengan kata lain, argumen pertama diteruskan ke 0 menjadi 8 dalam penutupan. Argumen lain apa pun diteruskan ke fungsi itu sendiri
Masuk ke mode layar penuh Keluar dari mode layar penuh Kami juga dapat dengan mudah mengakses properti _4 dan 5 tanpa mengubahnya. Jadi, saya bisa melakukannya
Masuk ke mode layar penuh Keluar dari mode layar penuh Sifat statisItu berfungsi dengan baik untuk properti atau metode non-statis. Bagaimana dengan yang statis?
Masuk ke mode layar penuh Keluar dari mode layar penuh Jadi, ini sedikit berbeda. Pertama, kami menggunakan _6 yang mengembalikan penutupan baru, yang telah diikat ulang ke objek atau kelas yang ditentukan. Dengan _7, Anda dapat meneruskan sebuah objek (seperti 0), atau Anda dapat membiarkan null itu dan meneruskan kelas, yang mengubah pengikatan statis. Itulah yang telah kami lakukan di sini. Dan karena mengembalikan penutupan baru, Anda kemudian harus memanggilnya, itulah sebabnya kami memiliki tambahan 9 setelahJadi, mari kita uraikan ini selangkah demi selangkah juga
Masuk ke mode layar penuh Keluar dari mode layar penuh Penutupan yang mengembalikan _0 dari cakupan saat ini
Masuk ke mode layar penuh Keluar dari mode layar penuh Penutupan baru, yang mengubah cakupan menjadi 1, artinya setiap referensi ke 2 mengacu pada 1
Masuk ke mode layar penuh Keluar dari mode layar penuh Atau, jika kita mengubah spesies menjadi nilai arbitrer, seperti yang kita lakukan pada yang ketiga
Masuk ke mode layar penuh Keluar dari mode layar penuh Menggunakan $changeAge = (fn (int $newAge) => $this->age = $newAge); _7 dengan objekAnda dapat menggunakan _7 dengan cara yang mirip dengan 0 0Masuk ke mode layar penuh Keluar dari mode layar penuh Mari kita hancurkan 1Masuk ke mode layar penuh Keluar dari mode layar penuh Penutupan yang memanggil _7 pada objek dalam lingkup saat ini 2Masuk ke mode layar penuh Keluar dari mode layar penuh Buat penutupan baru dengan _8 sebagai ruang lingkup. Dengan cara ini, setiap referensi ke _8 merujuk ke 8 _3Masuk ke mode layar penuh Keluar dari mode layar penuh Karena _1 adalah penutupan, kita harus benar-benar menyebutnyaKesimpulanTentu, kita dapat menggunakan 2 dan 3 untuk melakukan semua ini, tetapi teknik ini sangat menyederhanakannya, karena memanggil satu metode pribadi adalah satu baris kodeSaya benar-benar menggunakan ini dalam paket yang baru-baru ini saya tulis yang seharusnya membuat ini lebih mudah Dan untuk mengulangi, saya tidak menyarankan melakukan ini dalam kode produksi. Ada alasan visibilitas ada. Kita tidak boleh menghindarinya seperti ini dalam kode di server kita. Namun, jika kita perlu mengutak-atik beberapa objek untuk pengujian, teknik ini dapat menyederhanakannya untuk kita Bagaimana cara mengakses properti pribadi di PHP?php gunakan PhpPrivateAccess \MyClass; . $penutupan = \Penutupan. bind(function (MyClass $class) { return $class->property; }, null, MyClass. kelas); . "
Apa gunanya Setvalue() di PHP?Deskripsi ¶
. Sets (changes) the property's value.
Apa gunanya refleksi di PHP?Istilah "refleksi" dalam pengembangan perangkat lunak berarti bahwa suatu program mengetahui strukturnya sendiri pada waktu proses dan juga dapat memodifikasinya. Kemampuan ini juga disebut sebagai "introspeksi". Di area PHP, refleksi digunakan untuk memastikan keamanan jenis dalam kode program . |