Apa itu sihir dalam PHP? Ini biasanya berarti metode seperti 
_construct() atau 
__get() . Metode ajaib dalam PHP adalah celah yang membantu pengembang melakukan hal-hal menakjubkan. Jaringan ini penuh dengan instruksi untuk menggunakannya, yang mungkin Anda kenal. Tetapi bagaimana jika kita mengatakan bahwa Anda bahkan belum melihat keajaiban yang sebenarnya? Lagi pula, semakin Anda tahu bahwa Anda tahu segalanya, semakin banyak sihir yang menghindar dari Anda.

Mari kita jatuhkan kerangka aturan OOP yang sudah ada dan buat yang tidak mungkin dilakukan di sekolah sihir PHP. Guru magis utama dan pertama sekolah adalah 
Alexander Lisachenko ( 
NightTiger ). Dia akan mengajarkan pemikiran sulap dan mungkin Anda akan menyukai metode sulap, cara non-standar mengakses properti, mengubah konteks, pemrograman berorientasi aspek, dan filter aliran.
Alexander Lisachenko adalah kepala departemen pengembangan web dan arsitektur di Alpari. Penulis dan pengembang utama kerangka kerja berorientasi aspek 
Go! Aop . Pembicara di konferensi internasional tentang PHP.
Dalam film bagus "The Illusion of Deception" ada ungkapan:
"Semakin dekat kamu, semakin sedikit kamu melihat."
Hal yang sama dapat dikatakan tentang PHP, sebagai trik sulap yang memungkinkan Anda melakukan hal-hal yang tidak biasa. Tapi pertama-tama, itu dibuat untuk menipu Anda: "... tindakan yang dimaksudkan untuk menipu, baik sebagai cara menipu seseorang, atau sebagai lelucon atau bentuk hiburan."
Jika kami menggabungkan PHP dan mencoba menulis sesuatu yang ajaib di dalamnya, kemungkinan besar saya akan menipu Anda. Saya akan melakukan beberapa trik, dan Anda akan lama bertanya-tanya mengapa ini terjadi. Itu karena PHP adalah bahasa pemrograman yang dikenal karena hal-hal yang tidak biasa.
Peralatan sulap
Apa yang kita butuhkan dari peralatan sulap? Metode yang sangat familiar.
__construct(), __destruct(), __clone(),
__call(), __callStatic(),
__get(), __set(), __isset(), __unset(),
__sleep(), __wakeup(),
__toString(), __invoke(), __set_state(),
__debugInfo()Saya akan mencatat metode terakhir secara terpisah - dengan itu Anda dapat memutar hal-hal yang tidak biasa. Tapi itu belum semuanya.
- declare(ticks=1).
 
- debug_backtrace(). Ini adalah teman kita untuk memahami di mana kita berada dalam kode saat ini, untuk melihat siapa yang memanggil kita dan mengapa, dengan argumen apa. Berguna untuk memutuskan untuk tidak mengikuti semua logika.
 
- unset(), isset(). Tampaknya tidak ada yang istimewa, tetapi desain ini menyembunyikan banyak trik, yang akan kami pertimbangkan lebih lanjut.
 
- by-reference passing. Ketika kami melewati beberapa objek atau variabel dengan referensi, kami harus berharap bahwa beberapa sihir pasti akan terjadi pada Anda.
 
- bound closures. Pada penutupan dan fakta bahwa mereka dapat mengikat, Anda dapat membangun banyak trik.
 
- API Refleksi membantu membawa refleksi ke tingkat yang baru.
 
- API StreamWrapper.
 
Peralatan sudah siap - saya akan mengingatkan aturan sihir pertama.
Selalu menjadi pria terpintar di ruangan itu.
Trik # 1. Perbandingan yang tidak mungkin
Mari kita mulai dengan trik pertama, yang saya sebut Impossible Comparison.
Perhatikan kode ini dan lihat apakah ini bisa terjadi di PHP.

Ada variabel, kami menyatakan nilainya, dan kemudian tiba-tiba tidak sama dengan dirinya sendiri.
Bukan angka
Ada artefak magis seperti NaN - Bukan-nomor.

Fitur luar biasa adalah bahwa itu tidak sama dengan dirinya sendiri. Dan ini trik pertama kami: gunakan NaN untuk mengacaukan teman. Tetapi NaN bukan satu-satunya solusi untuk tugas ini.
Kami menggunakan konstanta

Kuncinya adalah kita dapat mendeklarasikan 
false sebagai 
true untuk 
namespace dan membandingkan. Pengembang yang tidak beruntung akan bertanya-tanya untuk waktu lama mengapa ada yang 
true dan tidak 
false .
Handler
Trik berikutnya adalah artileri yang lebih kuat dari dua opsi sebelumnya. Mari kita lihat cara kerjanya.

Triknya didasarkan pada 
tick_function dan, seperti yang saya sebutkan, 
declare(ticks=1) .
Bagaimana semuanya bekerja di luar kotak? Pertama, kami mendeklarasikan beberapa fungsi, dan dengan referensi dibutuhkan parameter 
isMagic , dan kemudian mencoba mengubah nilai ini menjadi 
true . Setelah kami mendeklarasikan 
declare(ticks=1) , penerjemah PHP memanggil 
register_tick_function - callback setelah setiap operasi dasar. Dalam panggilan balik ini, kita dapat mengubah nilai yang sebelumnya 
false menjadi 
true . Keajaiban!
Trik # 2. Ekspresi ajaib
Ambil contoh di mana dua variabel dideklarasikan. Salah satunya 
false , yang lain 
true . Kami 
isBlack dan 
isWhite dan var_dump hasilnya. Menurut Anda apa hasilnya?
 Operator prioritas
Operator prioritas . Jawaban yang benar 
false , karena dalam PHP ada yang namanya "operator didahulukan".

Anehnya, operator logis 
or prioritas kurang dari operasi penugasan. Oleh karena itu, hanya menetapkan 
false terjadi. Di 
isWhite bisa ada ekspresi lain yang akan dijalankan jika bagian pertama gagal.
Ekspresi ajaib
Lihatlah kode di bawah ini. Ada beberapa kelas yang berisi konstruktor, dan beberapa pabrik, kodenya akan lebih jauh.

Perhatikan baris terakhir.
 $value = new $factory->build(Foo::class); 
Ada beberapa opsi yang bisa terjadi.
- $factoryakan digunakan sebagai nama kelas yang- new;
 
- akan ada kesalahan penguraian;
 
- panggilan $factory->build()akan digunakan, nilai fungsi ini akan kembali, hasilnya akannew;
 
- nilai properti $factory->buildakan digunakan untuk membangun kelas.
 
Mari kita periksa ide terakhir. Di kelas 
$factory , kami mendeklarasikan serangkaian fungsi ajaib. Mereka akan menulis apa yang kita lakukan: memanggil properti, memanggil metode, atau bahkan mencoba memanggil 
invoke pada objek.
 class Factory { public function _get($name) {echo "Getting property {$name}"; return Foo::class;} public function _call($name, $arg) {echo "Calling method {$name}"; return Foo::class;} public function _invoke($name) {echo "Invoking {$name}"; return Foo::class;} } 
Jawaban yang benar: kami tidak memanggil metode, tetapi properti. Setelah 
$factory->build ada parameter untuk konstruktor, yang akan kami sampaikan ke kelas ini.
Omong-omong, dalam kerangka ini saya telah menerapkan fitur yang disebut "mencegat penciptaan objek baru" - Anda dapat "mengunci" desain ini.
Celah Parser
Contoh berikut adalah untuk parser PHP itu sendiri. Pernahkah Anda mencoba fungsi panggilan atau menetapkan variabel di dalam kurung kurawal?

Saya mendapatkan trik ini di Twitter, ini berfungsi sangat tidak standar.
 $result = ${'_' . !$_=getCallback()}(); $_=getCallback();  
Pertama, kami menetapkan nilai ekspresi ke variabel bernama 
_ (garis bawah). Kami sudah memiliki variabel, kami mencoba untuk membalikkan nilainya secara logis, dan kami mendapatkan 
false - garis dicor seolah-olah menjadi 
true . Kemudian kami merekatkan semuanya menjadi satu dalam nama variabel, yang kemudian kami masukkan ke dalam kurung keriting.
Apa itu sihir? Ini adalah hiburan yang memungkinkan kita untuk merasa terinspirasi, tidak biasa, katakan: βApa? Jadi itu mungkin?! β
Trik # 3. Melanggar aturan
Yang saya sukai tentang PHP adalah Anda bisa melanggar aturan yang dibuat semua orang dalam upaya untuk menjadi super aman. Ada desain yang disebut "kelas tertutup" yang memiliki konstruktor pribadi. Tugas Anda sebagai murid pesulap adalah membuat instance kelas ini.

Pertimbangkan tiga opsi untuk bagaimana melakukan ini.
Penanganan masalah
Cara pertama adalah yang paling jelas. Itu harus akrab bagi setiap pengembang - ini adalah API standar yang ditawarkan oleh bahasa tersebut kepada kami.

Konstruk 
newInstanceWithoutConstructor memungkinkan Anda untuk melewati batasan bahasa bahwa konstruktor bersifat pribadi dan membuat turunan kelas dengan melewati semua deklarasi konstruktor pribadi kami.
Opsi ini berfungsi, sederhana, tidak memerlukan penjelasan apa pun.
Hubungan pendek
Opsi kedua membutuhkan lebih banyak perhatian dan keterampilan. Fungsi anonim dibuat, yang kemudian mengikat osprey kelas itu.

Di sini kita berada di dalam kelas dan dapat memanggil metode pribadi dengan aman. Kami menggunakan ini dengan memanggil 
new static dari konteks kelas kami.

Deserialisasi
Opsi ketiga adalah yang paling maju, menurut saya.

Jika Anda menulis baris tertentu dalam format tertentu, gantikan nilai-nilai tertentu di sana - kelas kami akan berubah.

Setelah deserialisasi, kita mendapatkan 
instance kita.
paket doktrin / instantiator
Sihir sering menjadi kerangka atau perpustakaan yang terdokumentasi - misalnya, dalam 
doktrin / instantiator semua ini diterapkan. Kita dapat membuat objek apa pun dengan kode apa pun.
 composer show doctrine/instantiator --all name : doctrine/instantiator descrip. : A small, lightweight utility to instantiate objects in PHP without invoking their constructors keywords : constructor, instantiate type : library license : MIT License (MIT) 
Trik # 4. Mencegah akses properti
Awan berkumpul: kelas adalah rahasia, properti dan konstruktor bersifat pribadi, dan juga callback.
 class Secret { private $secret = 42; private function _construct() { echo 'Secret is: ', $this->secret; } private function onPropAccess(string $name) { echo "Accessing property {$name}"; return 100500; } }  
Tugas kita, sebagai penyihir, entah bagaimana untuk memanggil panggilan balik.
Menambahkan keajaiban ... pengambil
Tambahkan sejumput sihir untuk membuatnya bekerja.

Sejumput sihir ini adalah 
getter sihir. Itu memanggil fungsi, dan sejauh ini tidak ada hal buruk yang terjadi. Tapi kita akan menggunakan trik sebelumnya dan membuat instance dari objek ini melewati konstruk pribadi.

Sekarang kita perlu entah bagaimana memanggil panggilan balik.
"Tidak disetel" di dalam sirkuit
Untuk melakukan ini, buat penutupan. Di dalam penutupan yang ada dalam ruang lingkup kelas, kami menghapus variabel ini dengan fungsi 
unset() .

unset memungkinkan Anda untuk sementara mengecualikan variabel, yang akan memungkinkan metode sulap kami dipanggil.
Kami memanggil konstruktor pribadi
Karena kami memiliki konstruktor pribadi yang menampilkan 
echo , Anda bisa mendapatkan konstruktor ini, membuatnya dapat diakses dengan memanggilnya.

Jadi kelas rahasia kami hancur berkeping-keping.

Kami menerima pesan bahwa kami:
- dicegat;
 
- mengembalikan sesuatu yang sama sekali berbeda.
 
paket leedavis / altr-ego
Banyak sihir sudah didokumentasikan. Paket 
altr-ego hanya berpura-pura menjadi komponen Anda.
 composer show leedavis81/altr-ego --all name : leedavis81/altr-ego descrip. : Access an objects protected / private properties and methods keywords : php, break scope versions : dev-master, v1.0.2, v1.0.1, v1.0.0 type : library license : MIT License (MIT) 
Anda dapat membuat salah satu objek dan menempelkannya sebentar. Ini akan memungkinkan perubahan pada fasilitas. Dia akan berubah dengan patuh dan memenuhi semua keinginan Anda.
Trik # 5. Objek tidak berubah dalam PHP
Apakah ada objek yang tidak dapat diubah dalam PHP? Ya, dan waktu yang sangat, sangat lama.
 namespace Magic { $object = (object) [ "\0Secret\0property" => 'test' ]; var_dump($object); } 
Dapatkan mereka dengan cara yang menarik. Yang menarik adalah kita membuat array yang memiliki 
kunci khusus . Dimulai dengan konstruksi 
\0 - ini adalah karakter byte nol, dan setelah 
Secret kita juga melihat 
\0 .
Konstruk digunakan dalam PHP untuk mendeklarasikan properti pribadi di dalam kelas. Jika kita mencoba untuk melemparkan objek ke array, kita akan melihat kunci yang sama. Kami tidak memiliki apa-apa selain 
stdClass . Ini berisi properti pribadi dari kelas 
Secret , yang setara dengan 
test .
 object(stdClass) [1] private 'property' (Secret) => string 'test' (length=4) 
Satu-satunya masalah adalah - maka Anda tidak bisa mendapatkan properti ini dari sana. Itu dibuat, tetapi tidak tersedia.
Saya pikir itu agak merepotkan - kita memiliki benda yang tidak dapat diubah, tetapi Anda tidak dapat menggunakannya. Karena itu, saya memutuskan bahwa sudah waktunya untuk mengajukan keputusan saya. Saya menggunakan semua pengetahuan dan sihir saya yang tersedia di PHP untuk membuat konstruksi berdasarkan semua trik sulap kami.
Mari kita mulai dengan yang sederhana - buat DTO dan coba untuk mencegat semua properti di dalamnya (lihat trik sebelumnya).
Kami menyimpan di tempat yang aman nilai-nilai yang kami tangkap dari sana. Mereka tidak akan dapat diakses dengan metode apa pun: baik 
reflection , maupun penutupan, atau sihir lainnya. Tetapi ada ketidakpastian - apakah ada tempat seperti itu di PHP yang akan menjamin untuk menyimpan beberapa variabel sehingga tidak ada programmer muda yang licik bisa sampai di sana?
Kami menyediakan metode ajaib sehingga Anda dapat membaca nilai ini. Untuk melakukan ini, kami memiliki 
getters sihir, metode 
isset sihir yang memungkinkan kami untuk menyediakan API.
Mari kita kembali ke tempat yang dapat diandalkan dan mencoba mencari.
- Global variablesdibatalkan - siapa pun dapat mengubahnya.
 
- Public propertiesjuga tidak cocok.
 
- Protected propertiesbegitu-begitu saja, karena kelas anak akan melewati.
 
- Private properties. Tidak ada kepercayaan, karena melalui penutupan atau melalui- reflectiondapat diubah.
 
- Private static propertiesdapat dicoba, tetapi- reflectionjuga pecah.
 
Tampaknya tidak ada tempat untuk menyembunyikan nilai-nilai variabel. Tapi ada hal ajaib - 
Static variables in functions - ini adalah variabel yang ada di dalam fungsi.
Penyimpanan nilai yang aman
Saya bertanya kepada 
Nikita Popov dan 
Jay Watkins tentang hal itu di saluran Stack Overflow khusus.

Ini adalah fungsi di mana variabel statis dideklarasikan. Apakah mungkin untuk keluar dari itu, mengubahnya? Jawabannya adalah tidak.
Kami telah menemukan celah kecil di dunia variabel terlindungi lainnya dan kami ingin menggunakannya.
Melewati Nilai oleh Tautan
Kami akan menggunakannya secara non-standar sebagai properti objek. Tetapi Anda tidak dapat melewati properti, jadi kami menggunakan transfer nilai klasik dengan referensi.

Ternyata ada kelas di mana ada metode 
callStatic ajaib, dan variabel 
Static dideklarasikan di dalamnya. Dalam setiap panggilan ke beberapa fungsi, kami meneruskan nilai variabel dari objek yang tidak dapat diubah dengan merujuk ke semua metode bersarang kami. Jadi kami menyediakan konteks.
Simpan status
Mari kita lihat bagaimana negara diselamatkan.

Sederhana saja. Untuk objek yang ditransfer, kami menggunakan fungsi 
spl_object_id , yang mengembalikan pengenal terpisah untuk setiap instance. 
State yang sudah kita dapatkan dari objek mencoba menyelamatkan di sana. Tidak ada yang istimewa.
Terapkan status objek
Di sini sekali lagi ada konstruksi untuk meneruskan nilai dengan referensi dan properti 
unset . Kami menghapus semua properti saat ini, setelah sebelumnya menyimpannya dalam variabel Status, dan mengatur konteks ini untuk objek. Objek tidak lagi berisi properti apa pun, tetapi hanya pengenalnya, yang dideklarasikan menggunakan 
spl_object_id dan dilampirkan ke objek ini saat masih hidup.

Dapatkan Negara
Maka semuanya sederhana.

Kami mendapatkan konteks ini pada 
getter sihir dan memanggil properti kami darinya. Sekarang tidak ada seorang pun dan tidak ada yang dapat mengubah nilai setelah 
Trait terhubung.

Semua metode ajaib ditimpa dan menerapkan kekekalan objek.

lisachenko / objek-abadi
Seperti yang diharapkan, semuanya langsung diformalkan di perpustakaan dan siap digunakan.
 composer show /immutable-object --all name : /immutable-object descrip. : Immutable object library keywords : versions : * dev-master type : library license : MIT License (MIT) 
Perpustakaannya terlihat sangat sederhana. Kami menghubungkannya dan membuat kelas kami. Ini memiliki sifat yang berbeda: pribadi, dilindungi dan publik. Kami menghubungkan 
ImmutableTrait .

Setelah itu, Anda dapat memulai objek sekali - lihat nilainya. Itu benar-benar disimpan di sana dan bahkan terlihat seperti DTO nyata.
 object (MagicObject) [3] public 'value' => int 200 
Tetapi jika kita mencoba mengubahnya, misalnya, seperti ini ...

... maka segera dapatkan 
fatal exception . Kami tidak dapat mengubah properti karena properti itu tidak dapat diubah. Bagaimana bisa begitu?

Jika Anda terlibat dalam tantangan yang menarik dan mencoba merendahkannya, Anda mendapatkan yang berikut ini.

Ini hadiah saya. Segera setelah Anda mencoba untuk gagal di dalam PHPStorm di dalam kelas ini, itu akan langsung menghentikan eksekusi perintah Anda. Saya tidak ingin Anda mempelajari kode ini - terlalu berbahaya. Dia akan memperingatkan bahwa tidak ada yang bisa dilakukan.
Trik # 6. Pengolahan benang
Pertimbangkan desainnya.
 include 'php://filter/read=string.toupper/resource=magic.php'; 
Ada sesuatu yang ajaib: filter PHP, 
read , pada akhirnya semacam 
file magic.php 
terhubung . File ini terlihat sangat sederhana.
 <?php echo 'Hello, world!' 
Perhatikan bahwa kasingnya berbeda. Namun, jika kami "mengisi" file melalui desain kami, maka kami mendapatkan ini:
 HELLO, WORLD! 
Apa yang terjadi pada saat itu? Menggunakan konstruksi filter PHP di 
include memungkinkan Anda untuk menghubungkan filter apa pun, termasuk milik Anda, untuk menganalisis kode sumber. Anda mengelola semuanya dalam kode sumber ini. Anda dapat menghapus 
final dari kelas dan metode, membuat properti publik - apa pun yang Anda bisa crank melalui hal ini
Bagian dari kerangka aspek saya didasarkan pada ini. Ketika kelas Anda terhubung, itu menganalisis dan mengubahnya menjadi apa yang akan dieksekusi.
Di luar kotak di PHP sudah ada sejumlah filter siap pakai.
 var_dump(stream_get_filters()); array (size=10) 0 => string 'zlib.*' (length=6) 1 => string 'bzip2.*' (length=7) 2 => string 'convert.iconv.*' (length=15) 3 => string ' string.rotl3' (length=12) 4 => string 'string.toupper' (length=14) 5 => string 'string.tolower' (length=14) 6 => string 'string.strip_tags' (length=17) 7 => string 'convert.*' (length=9) 8 => string 'consumed' (length=8) 9 => string 'dechunk' (length=7) 
Mereka memungkinkan Anda untuk "zip" konten, menerjemahkannya ke huruf besar atau kecil.
Trik utama yang ingin saya tampilkan sudah berakhir. Sekarang mari kita beralih ke intisari dari semua yang bisa saya lakukan - pemrograman berorientasi aspek.
Trik # 7. Pemrograman Berorientasi Aspek
Lihatlah kode ini dan pikirkan apakah itu baik atau buruk dari sudut pandang Anda.

Kode tampaknya cukup memadai. Ia memeriksa hak akses, melakukan pencatatan, membuat pengguna, tetap ada, mencoba menangkap 
exception .
Jika Anda melihat semua mie ini, mie ini diulang dalam setiap metode kami, dan satu-satunya hal yang berharga di sini adalah mie itu ditandai dengan warna hijau.

Yang lainnya: "keprihatinan sekunder" atau "keprihatinan lintas sektoral" adalah fungsi lintas sektoral.
OOP konvensional membuat tidak mungkin untuk menyalin semua struktur ini dengan copy-paste, menghapusnya, dan mengeluarkannya di suatu tempat. Ini buruk karena Anda harus mengulanginya. Saya berharap kode selalu terlihat bersih dan rapi.

Sehingga tidak mengandung logging (biarkan diterapkan entah bagaimana) dan tidak mengandung 
security .

Jadi itu saja, termasuk masuk ...

... dan pemeriksaan keamanan, ...

... dilakukan dengan sendirinya.
Dan itu mungkin.
Glosarium "Aspek"
Ada hal yang disebut Aspect. Ini adalah contoh sederhana yang memeriksa izin. Berkat dia, Anda dapat melihat beberapa anotasi, yang juga disorot oleh plugin untuk PhpStorm. "Aspect" menyatakan ekspresi SQL yang menunjukkan kode untuk menerapkan kondisi ini. Di bawah, misalnya, kami ingin menerapkan penutupan untuk semua metode publik dari kelas 
UserService .

Kami mendapatkan penutupan menggunakan metode 
$invocation .

Ini adalah semacam pembungkus di atas metode 
reflection , yang berisi lebih banyak argumen.
Lebih lanjut dalam panggilan balik ini untuk setiap metode, Anda dapat memeriksa hak akses yang diperlukan, ini disebut "Saran".

Kami agak mengatakan bahasanya: "PHP yang terhormat, mohon terapkan metode ini sebelum setiap panggilan ke metode publik dari kelas 
UserService " Hanya satu baris, tetapi banyak yang bermanfaat.
Aspek vs Pendengar Acara
Untuk membuatnya lebih jelas, saya membuat perbandingan Aspect dengan Event Listener. Banyak yang bekerja di Symfony dan tahu apa itu Event Dispatcher.

Mereka serupa di mana kita melewati semacam ketergantungan, misalnya, 
AutorizationChecker , dan menyatakan di mana harus diterapkan dalam kasus ini. Dalam kasus Listener, ini adalah 
SubscrabingEvent disebut 
UserCreate , dan dalam kasus 
Aspect kami berlangganan semua panggilan ke metode publik dari 
UserService .
Pada saat yang sama, isi dari penangan panggilan balik itu sendiri kira-kira sama: kami hanya memeriksa sesuatu dan bereaksi sesuai.Pertimbangkan cara kerjanya di bawah tenda.Langkah pertama yang membutuhkan kerangka aspek adalah pendaftaran Aspects . Tahap kedua . Untuk menangani ini, trik sebelumnya dengan filter PHP digunakan lagi .
Tahap kedua . Untuk menangani ini, trik sebelumnya dengan filter PHP digunakan lagi . Ini adalah komponen khusus yang mengubah kode sumber. Dia melakukan ini secara diam-diam, tetapi dia akan bekerja dengan baik dalam produksi, karena dia terintegrasi dengan OPcache.Tahap ketiga . Semuanya terintegrasi pada level
Ini adalah komponen khusus yang mengubah kode sumber. Dia melakukan ini secara diam-diam, tetapi dia akan bekerja dengan baik dalam produksi, karena dia terintegrasi dengan OPcache.Tahap ketiga . Semuanya terintegrasi pada level Composer. Setelah Go diinstal! AOP, dia mulai berkomunikasi dengan dekatComposer , .

Aspects , 
Aspects . .
.
PHP-Parser . , , 
. , 
, 
PHP-Parser . .

. , 
goaop/parser-reflection .

AST- , . , , , .
.

, , 
Aspect .

, .

, , . β , - , .

, . , .
Aspect MOCK. «», , . .
β 
joinPoint . - 
joinPoint : , , .
Apa selanjutnya
.
OPcache preloading for AOP Core . AOP- . 10 . Bootstrapping , PHP.
FFI integration to modify binary opcodes . , , . PHP-opcodes, 
.bin . FFI .
Modifying PHP engine internal callbacks PHP- userland. PHP . FFI PHP userland, , , . .
, .
#8. goaop/framework
, 
GitHub .
 composer show goaop/framework --all name : goaop/framework descrip. : Framework for aspect-oriented programming in PHP. keywords : php, aop, library, aspect versions : dev-master, 3.0.x-dev, 2.x-dev, 2.3.1, β¦ type : library license : MIT License 
, PhpStorm.

, Pointcuts. , , . β , , .
Trick #9.
. , .
: , - . 
fastcgi_finish_request . , , , - callback β .
?
, 
Deffered , , .

Aspect , , , 
Deffered , .

Aspect : , , , callback, , callback. .
React , 
promise . , - , - , .
, .

shutdown_function Aspect . , callback, , , , callback 
onPhpTerminate . 
fastcgi_finish_request : Β«, , , , Β». .
, 
sendPushNotification .

, - β 2 .

, , , 2 .
, 
Deferred .

, . - , , .
Itu saja. , - . , .
PHP Russia 2020 . β . telegram- , PHP Russia 2020.