Halo semuanya!
Bulan ini kami menyelesaikan set pertama kursus
Pengembang PHP Backend dan merekrut mereka dengan sekuat tenaga (sebanyak mungkin selama liburan). Kursus ini diisi ulang dengan guru lain -
Evgeny Volosatov , yang mungkin banyak orang tahu. Yah, secara tradisional kami berbagi hal-hal menarik.
Ayo pergi.
Dalam aplikasi apa pun, ada bagian kode yang memotong beberapa bagian arsitektur secara bersamaan.
Masalah ini tidak begitu jelas ketika bekerja dengan kerangka kerja yang berfungsi penuh. Kemungkinan besar masalah Anda akan meluas, dan akan ada kemungkinan bahwa kerangka tersebut telah menyelesaikannya dengan mengorbankan pembagian tanggung jawab atau dengan memberikan abstraksi di atas kerangka tersebut. Banyak kerangka kerja menggunakan arsitektur berorientasi peristiwa untuk menyelesaikan masalah fungsionalitas ujung ke ujung. Tapi selalu ada saat ketika kerangka kerja tidak dapat memberikan tingkat kontrol yang diinginkan atas sepotong logika tertentu. Ini terutama benar ketika menggunakan mikroframe atau pengembangan dengan perpustakaan khusus. Semakin banyak aplikasi Anda mempertimbangkan prinsip pemisahan tanggung jawab, semakin besar peran fungsi ujung ke ujung dalam arsitektur Anda.

Pemrograman PHP Berorientasi Aspek
Aspect Oriented Programming (AOP) adalah paradigma pemrograman yang berfokus pada pengorganisasian dan modulasi fungsi ujung-ke-ujung. Kasus aplikasi - ACL, pencatatan, penanganan kesalahan, caching.
Asumsi internal (internal) PHP (ketika Anda mendefinisikan fungsi / konstanta / kelas, tetap didefinisikan selamanya) membuat paradigma AOP sulit untuk diimplementasikan.
Li3 adalah yang pertama untuk memecahkan masalah fungsionalitas ujung ke ujung menggunakan mekanisme penyaringan yang memungkinkan penyaringan logika suatu metode melalui penutupan. Untuk membuat metode ini dapat difilter, implementasi Li3 membutuhkan penambahan kode template secara manual. Dengan keterbatasan seperti itu, teknik AOP terbatas pada teknik penyaringan.
Implementasi AOP terkenal lainnya di PHP:
Ekstensi PECL AOP adalah pendekatan yang menarik tetapi pada saat yang sama berisiko, karena dukungan untuk ekstensi PECL tidak umum. Pilihan lain adalah Go! Libraries, yang merupakan implementasi AOP yang memperbaiki kode PHP dengan cepat, yang memungkinkan untuk menggunakan metode AOP.
Ada implementasi lain, tetapi sebagian besar dibangun berdasarkan proxy (sejauh yang saya tahu), dan pendekatan ini memiliki banyak keterbatasan.
Orang baru di daerah itu
Pembuatan kode otomatis telah lama digunakan dalam PHP dan digunakan di banyak perpustakaan, misalnya
ProxyManager. Dan terima kasih atas adopsi Komposer,
Go! menunjukkan bahwa mengedit kode dengan cepat dimungkinkan.
Jika pembuatan kode masih dapat dianggap sederhana, maka memperbaiki kode agak lebih rumit. Pertama, di PHP tidak ada kode parser bawaan, dan kedua, ada sangat sedikit pustaka yang memecahkan masalah parsing kode PHP. Yang paling terkenal adalah perpustakaan
PHP-Parser . PHP-Parser adalah alat yang hebat, tetapi bahkan mengabaikan pemformatan ruang dalam pohon sintaksis abstrak yang dihasilkan. Yang membuatnya sulit untuk memperbaiki kode. Memang, kode yang perlu diperbaiki adalah kode yang dapat dieksekusi nyata. Oleh karena itu, jika Anda ingin pelacakan mundur akurat dengan kesalahan, Anda perlu mempertimbangkan nomor baris dalam file yang diperbaiki.
Untuk tugas ini, kami menggunakan
patcher kode Kahlan JIT. Kahlan adalah kerangka uji Unit & BDD baru, berkat teknik pengeditan JIT, yang memungkinkan kode patch stub dan monyet langsung di Ruby atau JavaScript. Di bawah tenda, kami menemukan bahwa perpustakaan ini didasarkan pada parser PHP yang belum sempurna. Tetapi, bagaimanapun, itu cukup cepat dan stabil untuk kita.
Pustaka filter tersedia di
github.com/crysalead/filter dan dapat digunakan sebagai berikut.
Pertama, patcher kode JIT harus diinisialisasi sesegera mungkin (misalnya, segera setelah menyalakan komposer autoloade):
include __DIR__ . '/../vendor/autoload.php'; use Lead\Filter\Filters; Filters::patch(true);
Perhatikan bahwa pengeditan kode hanya dimungkinkan untuk kelas yang dimuat oleh komposer autoload'er. Jika sebuah kelas ditambahkan menggunakan ekspresi need atau include, itu sudah dimuat sebelum memanggil Filter :: patch (true), dan karenanya tidak akan diperbaiki.
Secara default, semua kode yang diperbaiki akan disimpan di / tmp / jit, tetapi Anda selalu dapat mengubahnya ke kode Anda sendiri:
Filters::patch(true, ['cachePath' => 'my/cache/path/jit']);
File yang di-cache akan dipulihkan secara otomatis setiap kali Anda mengubah file PHP.
Perhatian!
Filters::patch(true)
adalah cara termudah untuk mengonfigurasi patcher, perlu diingat bahwa semua kode Anda akan diperbaiki. Butuh waktu lama untuk membungkus semua metode dalam basis kode Anda dalam penutupan filter.
Untungnya, jika fungsionalitas ujung ke ujung memainkan peran penting dalam kode yang dirancang dengan baik, hanya beberapa metode yang diperlukan dalam proyek. Oleh karena itu, pendekatan yang disukai adalah untuk memperbaiki hanya metode-metode yang akan difilter:
Filters::patch([ 'A\ClassName', 'An\Example\ClassName::foo', 'A\Second\Example\ClassName' => ['foo', 'bar'], ], [ 'cachePath' => 'my/cache/path/jit', ]);
Dengan demikian, Anda dapat memilih untuk memperbaiki semua metode dari kelas tertentu, hanya satu metode atau beberapa di antaranya.
Filter API
Sekarang setelah patcher JIT diaktifkan, buat filter log:
use Chaos\Filter\Filters; use Chaos\Database\Database; use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('database'); $logger->pushHandler(new StreamHandler('my/log/path/db.log', Logger::WARNING)); Filters::apply(Database::class, 'query', function($next, $sql, $data, $options) use ($logger) { $logger->info('Ran SQL query: ' . $sql); return $next($sql, $data, $options); });
Contoh di atas membuat filter log kueri SQL untuk pustaka database Chaos. Informasi lebih lanjut tentang filter API dapat ditemukan di
github.com/crysalead/filter .
Kesimpulan
AOP, menurut saya, adalah jawaban nyata untuk fungsionalitas ujung ke ujung. Semua abstraksi lainnya sama-sama berlebihan dan dalam banyak kasus terbatas pada kerangka kerja tertentu. Saya tidak kehilangan harapan bahwa suatu hari PHP akan menyediakan API bawaan untuk pemrograman berorientasi aspek. Tapi sekarang, saya pikir, patch kode JIT adalah pilihan terbaik, di mana kelebihannya jauh melebihi biaya overhead CPU, yang secara praktis dapat diabaikan ketika patching kode JIT tidak diterapkan secara global.
AKHIR
Seperti biasa, kami berharap, jika ada, pertanyaan, keinginan dan mengundang Anda ke
pelajaran terbuka di mana Anda dapat mendengarkan ceramah yang menarik dan mengenal
guru baru dengan lebih baik.