Pemicu aksi dan pendengar peristiwa
Sekilas pandang
Bagian berjudul “Sekilas pandang”NextPDF memicu peristiwa siklus hidup melalui sistem dalam NextPDF\Event yang kompatibel dengan PHP Standards Recommendation 14 (PSR-14). Daftarkan pendengar, tetapkan prioritas, dan tanggapi saat dokumen dibuat, halaman ditambahkan, fon dimuat, penandatanganan atau enkripsi berjalan, bita ditulis, atau keluaran dimulai. Hentikan rantai hanya saat benar-benar diperlukan.
Pemasangan
Bagian berjudul “Pemasangan”composer require nextpdf/core:^3Tinjauan konseptual
Bagian berjudul “Tinjauan konseptual”Sistem peristiwa memiliki dua komponen publik. ListenerProvider memetakan setiap kelas peristiwa ke daftar pendengar callable yang sudah diurutkan. EventDispatcher menelusuri daftar tersebut dan memanggil tiap pendengar menurut urutan prioritas. Kedua kelas bersifat final, jadi perluas perilakunya melalui komposisi, bukan subkelas.
Kedua kelas sesuai dengan PSR-14 melalui duck typing. EventDispatcher::dispatch() menggunakan signature dispatch() PSR-14 dan mengembalikan peristiwa setelah setiap pendengar berjalan. ListenerProvider::getListenersForEvent() menggunakan signature provider PSR-14. NextPDF tidak memerlukan paket PSR-14. Jika proyek Anda memasangnya, antarmukanya tetap selaras.
Dua perilaku penting bagi penulis ekstensi:
- Pendengar wildcard. Saat menyelesaikan daftar pendengar, provider menelusuri kelas induk dan antarmuka peristiwa. Pasangkan pendengar ke kelas dasar
AbstractEventuntuk mengamati setiap peristiwa siklus hidup. Pasangkan satu pendengar ke antarmuka untuk menangkap satu keluarga. - Prioritas dan propagasi. Prioritas yang lebih tinggi berjalan lebih dulu. Prioritas yang sama mempertahankan urutan pendaftaran. Setiap peristiwa yang memperluas
AbstractEventdapat dihentikan. Pendengar dapat memanggilstopPropagation(), lalu dispatcher melewati pendengar yang tersisa.
Dispatcher memiliki jalur cepat tanpa overhead. Ketika tidak ada pendengar yang terikat ke suatu kelas peristiwa atau kelas induk mana pun, dispatch() langsung kembali setelah satu pemeriksaan hasListeners().
Peristiwa siklus hidup
Bagian berjudul “Peristiwa siklus hidup”| Peristiwa | Ruang nama | Dipicu saat | Stabilitas |
|---|---|---|---|
DocumentCreatedEvent | NextPDF\Event\Document | Konstruksi dokumen telah selesai | eksperimental |
PageAddedEvent | NextPDF\Event\Document | Halaman selesai diinisialisasi sepenuhnya | eksperimental |
ContentRenderedEvent | NextPDF\Event\Content | Konten dirender ke halaman | eksperimental |
FontLoadedEvent | NextPDF\Event\Content | Keluarga dan gaya fon dimuat untuk pertama kali | eksperimental |
SignatureAppliedEvent | NextPDF\Event\Security | Bita tanda tangan disematkan | eksperimental |
EncryptionAppliedEvent | NextPDF\Event\Security | Enkripsi dikonfigurasi | eksperimental |
PdfSerializedEvent | NextPDF\Event\Writer | Serialisasi selesai | eksperimental |
DocumentOutputEvent | NextPDF\Event\Document | Pengiriman keluaran akan segera dimulai | eksperimental |
Dispatcher, provider, antarmuka penanda, dan kelas dasar bersifat stable (sejak 3.0.0). Muatan peristiwa bersifat experimental. Argumen konstruktor dan properti readonly-nya dapat berubah dalam rilis minor. Rilis tambalan hanya bersifat menambahkan. Saat mengikat ke nama properti muatan, pertimbangkan batasan tersebut.
Permukaan API
Bagian berjudul “Permukaan API”NextPDF\Event\ListenerProvider (stabil, final):
| Metode | Mengembalikan | Tujuan |
|---|---|---|
addListener(string $eventClass, callable $listener, int $priority = 0) | void | Daftarkan pendengar; prioritas yang lebih tinggi berjalan lebih dulu. Melempar InvalidConfigException ketika kelasnya kosong. |
getListenersForEvent(EventInterface $event) | list<callable> | Menyelesaikan daftar pendengar, termasuk pendaftaran pada induk dan antarmuka. |
hasListeners(string $eventClass) | bool | Periksa hierarki kelas tanpa overhead. |
getListenerCount(string $eventClass) | int | Hanya menghitung pendaftaran langsung. |
clearListeners() | void | Atur ulang provider. |
NextPDF\Event\EventDispatcher (stabil, final):
| Metode | Mengembalikan | Tujuan |
|---|---|---|
dispatch(EventInterface $event) | EventInterface | Memanggil pendengar menurut urutan prioritas, menghormati penghentian propagasi, dan mengembalikan peristiwa. |
getListenerProvider() | ListenerProvider | Akses provider untuk menambahkan pendengar saat runtime. |
Dokumen yang memicu peristiwa menggunakan NextPDF\Event\EventAwareDocumentTrait. Metode setEventDispatcher()-nya menghubungkan dispatcher ke satu dokumen. Tanpa dispatcher, setiap helper dispatch tidak melakukan apa pun.
Contoh kode — Mulai cepat
Bagian berjudul “Contoh kode — Mulai cepat”<?php
declare(strict_types=1);
use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use NextPDF\Event\Security\SignatureAppliedEvent;
$listeners = new ListenerProvider();$listeners->addListener( SignatureAppliedEvent::class, static function (SignatureAppliedEvent $event): void { \error_log("Signed at level {$event->signatureLevel} by {$event->signerName}"); }, priority: 100,);
$dispatcher = new EventDispatcher($listeners);Contoh kode — Produksi
Bagian berjudul “Contoh kode — Produksi”Pendengar audit produksi ini memakai prioritas tinggi agar berjalan lebih dulu, menulis log terstruktur, dan menambahkan pendengar penangkap-semua pada kelas dasar demi kelengkapan.
<?php
declare(strict_types=1);
use NextPDF\Event\AbstractEvent;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use NextPDF\Event\Security\EncryptionAppliedEvent;use NextPDF\Event\Security\SignatureAppliedEvent;use Psr\Log\LoggerInterface;
final class SecurityAuditSubscriber{ public function __construct(private readonly LoggerInterface $logger) {}
public function register(ListenerProvider $listeners): EventDispatcher { $listeners->addListener( SignatureAppliedEvent::class, function (SignatureAppliedEvent $event): void { $this->logger->info('signature.applied', [ 'level' => $event->signatureLevel, 'signer' => $event->signerName, ]); }, priority: 1000, );
$listeners->addListener( EncryptionAppliedEvent::class, function (EncryptionAppliedEvent $event): void { $this->logger->info('encryption.applied', [ 'algorithm' => $event->algorithm, ]); }, priority: 1000, );
// Catch-all: observe every lifecycle event for trace completeness. $listeners->addListener( AbstractEvent::class, fn (AbstractEvent $event): mixed => $this->logger->debug('lifecycle', ['event' => $event->getEventName()]), priority: -1000, );
return new EventDispatcher($listeners); }}Kasus tepi & jebakan
Bagian berjudul “Kasus tepi & jebakan”- Kelas final.
EventDispatcherdanListenerProviderbersifatfinal. Gunakan keduanya melalui komposisi; jangan membuat subkelasnya. - Kelas peristiwa kosong melempar.
addListener('', ...)melemparInvalidConfigException. Selalu berikan konstanta class-string. - Biaya wildcard. Pendengar pada
AbstractEventdipicu untuk setiap peristiwa. Beri pendengar penangkap-semua prioritas rendah, dan jaga agar tetap ringan. - Mutasi keluaran.
DocumentOutputEventmembawa bita Portable Document Format (PDF). Mesin membacanya kembali setelah dispatch. Jika Anda mengubah bita tersebut, Anda memperoleh kendali yang besar sekaligus risiko yang besar. Offset bita yang salah merusak PDF dan dapat memutus tanda tangan. Sebaiknya hanya mengamati, kecuali Anda sepenuhnya mengendalikan hasilnya demi determinisme dan tanda tangan. - Tanpa dispatcher, tanpa peristiwa. Dokumen yang tidak memiliki dispatcher yang diatur melalui
EventAwareDocumentTraittidak memicu peristiwa apa pun. Ini adalah jalur tanpa overhead yang disengaja, bukan kesalahan penyiapan.
Kinerja
Bagian berjudul “Kinerja”Jalur cepatnya adalah satu pemeriksaan rantai induk hasListeners(). Tanpa pendengar, dispatch nyaris gratis. Provider menyimpan cache daftar pendengar yang terurut per kelas peristiwa dan menghapus cache itu hanya ketika pendengar berubah. Jaga agar pendengar tidak melakukan operasi yang memblokir karena semuanya berjalan inline pada jalur rendering.
Catatan keamanan
Bagian berjudul “Catatan keamanan”SignatureAppliedEvent dan EncryptionAppliedEvent adalah jangkar audit. Daftarkan pendengar berprioritas tinggi untuk mencatat penandatanganan dan enkripsi ke penyimpanan yang dapat memperlihatkan upaya pengubahan. Jangan menghentikan rantai pada peristiwa keamanan kecuali Anda berniat membungkam pendengar berikutnya. Menghentikannya dapat secara diam-diam menonaktifkan kait audit yang berjalan setelahnya.
Kesesuaian
Bagian berjudul “Kesesuaian”Halaman ini tidak membuat klaim normatif apa pun di luar kompatibilitas PSR-14. Kompatibilitas itu berbasis duck typing dan tidak memerlukan paket PSR-14.
Konteks komersial
Bagian berjudul “Konteks komersial”NextPDF Enterprise menyertakan pendengar yang telah diaudit untuk peristiwa tanda tangan dan enkripsi yang memasok log audit yang dapat memperlihatkan upaya pengubahan. Karena kontrak pendengar adalah application programming interface (API) peristiwa publik, pendengar Anda sendiri dapat berdampingan dengan pendengar Enterprise pada provider yang sama.
Lihat juga
Bagian berjudul “Lihat juga”- Tinjauan penulisan ekstensi
- Fon kustom
- Tata letak kustom dan intersepsi teks
- Kontrak provider Key Management Service (KMS)
- Aturan stabilitas Service Provider Interface (SPI)
Kontrak dan modul terkait
Bagian berjudul “Kontrak dan modul terkait”- Referensi modul Event — taksonomi peristiwa siklus hidup PSR-14 dan dispatcher internal.
- Referensi kontrak penandatanganan — kontrak di balik
SignatureAppliedEvent. - Aturan stabilitas SPI — bagaimana dispatcher yang stabil dan muatan eksperimental diberi versi.
- Fon kustom — memasangkan
FontLoadedEventdengan kontrak registri. - Tinjauan penulisan ekstensi — keseluruhan permukaan SPI publik.
Glosarium mendefinisikan istilah pendengar peristiwa, dispatcher peristiwa, listener provider, dan peristiwa yang dapat dihentikan yang digunakan pada halaman ini. Lihat glosarium yang diterbitkan untuk definisi kanonis.