Eylem tetikleyicileri ve olay dinleyicileri
Bir bakışta
“Bir bakışta” başlıklı bölümNextPDF, yaşam döngüsü olaylarını NextPDF\Event içinde yer alan ve PHP Standards Recommendation 14 (PSR-14) ile uyumlu bir sistem üzerinden tetikler. Bir dinleyici kaydedin, bir öncelik belirleyin ve bir belge oluşturulduğunda, bir sayfa eklendiğinde, bir yazı tipi yüklendiğinde, imzalama veya şifreleme çalıştığında, baytlar yazıldığında ya da çıktı başladığında tepki verin. Zinciri yalnızca gerektiğinde durdurun.
Kurulum
“Kurulum” başlıklı bölümcomposer require nextpdf/core:^3Kavramsal genel bakış
“Kavramsal genel bakış” başlıklı bölümOlay sisteminde herkese açık iki parça bulunur. ListenerProvider, her olay sınıfını çağrılabilir dinleyicilerden oluşan sıralı bir listeyle eşler. EventDispatcher, bu listenin üzerinden geçer ve her dinleyiciyi öncelik sırasına göre çağırır. Her iki sınıf da final olduğundan, davranışı alt sınıflama yerine bileşimle genişletin.
Her iki sınıf da ördek tiplemesi yoluyla PSR-14 ile uyumludur. EventDispatcher::dispatch(), PSR-14 dispatch() imzasını kullanır ve dinleyiciler çalıştıktan sonra olayı döndürür. ListenerProvider::getListenersForEvent(), PSR-14 sağlayıcı imzasını kullanır. NextPDF, PSR-14 paketini gerektirmez. Projeniz bu paketi kurarsa, arabirimler yine de uyumlu kalır.
Eklenti yazarları için iki davranış önemlidir:
- Joker karakterle dinleme. Sağlayıcı, dinleyicileri çözümlerken olayın üst sınıflarını ve arabirimlerini dolaşır. Her yaşam döngüsü olayını izlemek için bir dinleyiciyi
AbstractEventtemel sınıfına bağlayın. Bir olay ailesini yakalamak için bir dinleyiciyi bir arabirime bağlayın. - Öncelik ve yayılım. Daha yüksek öncelik önce çalışır. Eşit öncelikler kayıt sırasını korur.
AbstractEventsınıfını genişleten her olay durdurulabilir. Bir dinleyicistopPropagation()çağırabilir ve dağıtıcı bundan sonra kalanları atlar.
Dağıtıcıda sıfır maliyetli bir hızlı yol bulunur. Bir olay sınıfına veya herhangi bir üst sınıfına bağlı dinleyici yoksa, dispatch() tek bir hasListeners() denetiminin hemen ardından geri döner.
Yaşam döngüsü olayları
“Yaşam döngüsü olayları” başlıklı bölüm| Olay | Ad alanı | Tetiklendiği zaman | Kararlılık |
|---|---|---|---|
DocumentCreatedEvent | NextPDF\Event\Document | Belge oluşturma tamamlanır | deneysel |
PageAddedEvent | NextPDF\Event\Document | Bir sayfa tamamen ilklenir | deneysel |
ContentRenderedEvent | NextPDF\Event\Content | İçerik bir sayfaya işlenir | deneysel |
FontLoadedEvent | NextPDF\Event\Content | Bir yazı tipi ailesi ve stili ilk kez yüklenir | deneysel |
SignatureAppliedEvent | NextPDF\Event\Security | İmza baytları gömülür | deneysel |
EncryptionAppliedEvent | NextPDF\Event\Security | Şifreleme yapılandırılır | deneysel |
PdfSerializedEvent | NextPDF\Event\Writer | Serileştirme tamamlanır | deneysel |
DocumentOutputEvent | NextPDF\Event\Document | Çıktı teslimi başlamak üzeredir | deneysel |
Dağıtıcı, sağlayıcı, işaretleyici arabirim ve temel sınıf stable kararlılık düzeyindedir (3.0.0 sürümünden beri). Olay yükleri experimental kararlılık düzeyindedir. Bu yüklerin kurucu bağımsız değişkenleri ve salt okunur özellikleri bir ara sürümde değişebilir. Yama sürümleri yalnızca ekleme yapar. Yük özellik adlarına bağımlı olurken bu kısıtlamayı göz önünde bulundurun.
API yüzeyi
“API yüzeyi” başlıklı bölümNextPDF\Event\ListenerProvider (stable, final):
| Yöntem | Döndürdüğü değer | Amaç |
|---|---|---|
addListener(string $eventClass, callable $listener, int $priority = 0) | void | Bir dinleyici kaydedin; daha yüksek öncelik önce çalışır. Sınıf boşsa InvalidConfigException fırlatır. |
getListenersForEvent(EventInterface $event) | list<callable> | Üst sınıflara ve arabirimlere ait kayıtlar da dahil olmak üzere dinleyicileri çözümleyin. |
hasListeners(string $eventClass) | bool | Sınıf hiyerarşisini ek yük olmadan denetleyin. |
getListenerCount(string $eventClass) | int | Yalnızca doğrudan kayıtları sayın. |
clearListeners() | void | Sağlayıcıyı sıfırlayın. |
NextPDF\Event\EventDispatcher (stable, final):
| Yöntem | Döndürdüğü değer | Amaç |
|---|---|---|
dispatch(EventInterface $event) | EventInterface | Dinleyicileri öncelik sırasına göre çağırın, yayılımın durdurulmasına uyun ve olayı döndürün. |
getListenerProvider() | ListenerProvider | Çalışma zamanında dinleyici eklemek için sağlayıcıya erişin. |
Olay tetikleyen belgeler NextPDF\Event\EventAwareDocumentTrait kullanır. Bu trait’in setEventDispatcher() yöntemi, bir dağıtıcıyı tek bir belgeye bağlar. Dağıtıcı yoksa dağıtım yardımcılarının hiçbiri işlem yapmaz.
Kod örneği — hızlı başlangıç
“Kod örneği — hızlı başlangıç” başlıklı bölüm<?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);Kod örneği — üretim
“Kod örneği — üretim” başlıklı bölümBu üretim denetim dinleyicisi, önce çalışmak için yüksek öncelik kullanır, yapılandırılmış günlükler yazar ve eksiksiz izleme için temel sınıfa tümünü yakalayan bir dinleyici ekler.
<?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); }}Uç durumlar ve tuzaklar
“Uç durumlar ve tuzaklar” başlıklı bölüm- Final sınıflar.
EventDispatcherveListenerProvidersınıflarıfinalsınıflardır. Bunları bileşimle kullanın; alt sınıf oluşturmayın. - Boş olay sınıfı hata fırlatır.
addListener('', ...)çağrısıInvalidConfigExceptionfırlatır. Her zaman bir class-string sabiti geçirin. - Joker karakter maliyeti.
AbstractEventüzerindeki bir dinleyici her olay için tetiklenir. Tümünü yakalayan dinleyicilere düşük öncelik verin ve onları ucuz tutun. - Çıktı değişikliği.
DocumentOutputEventTaşınabilir Belge Biçimi (PDF) baytlarını taşır. Motor, dağıtımın ardından bu baytları yeniden okur. Bu baytları değiştirirseniz kapsamlı bir denetim yükünü ve geniş bir riski üstlenirsiniz. Hatalı bir bayt uzaklığı PDF’yi bozar ve bir imzayı geçersiz kılabilir. Sonucun belirliliği ve imzalar için sorumluluğu üstlenmediğiniz sürece yalnızca gözlemlemeyi tercih edin. - Dağıtıcı yok, olay yok.
EventAwareDocumentTraitüzerinden ayarlanmış bir dağıtıcısı olmayan bir belge hiçbir olay tetiklemez. Bu, bir kurulum hatası değil, amaçlanan sıfır maliyetli yoldur.
Başarım
“Başarım” başlıklı bölümHızlı yol, tek bir hasListeners() üst zincir denetiminden oluşur. Hiç dinleyici yokken, dağıtım neredeyse maliyetsizdir. Sağlayıcı, sıralanmış dinleyici listesini her olay sınıfı için önbelleğe alır ve bu önbelleği yalnızca dinleyiciler değiştiğinde temizler. Dinleyicilerin engelleyici olmamasını sağlayın, çünkü bunlar işleme yolu üzerinde satır içi çalışır.
Güvenlik notları
“Güvenlik notları” başlıklı bölümSignatureAppliedEvent ve EncryptionAppliedEvent denetim için çapa noktalarıdır. İmzalama ve şifreleme işlemlerini kurcalamayı belli eden bir depoya günlüğe yazmak için yüksek öncelikli dinleyiciler kaydedin. Daha sonraki dinleyicileri susturmayı amaçlamadığınız sürece zinciri bir güvenlik olayında durdurmayın. Zinciri durdurmak, daha sonra çalışacak denetim kancalarını sessizce devre dışı bırakabilir.
Uygunluk
“Uygunluk” başlıklı bölümBu sayfa, PSR-14 uyumluluğunun ötesinde hiçbir normatif iddiada bulunmaz. Bu uyumluluk yalnızca ördek tiplemesi düzeyindedir ve PSR-14 paketini gerektirmez.
Ticari bağlam
“Ticari bağlam” başlıklı bölümNextPDF Enterprise, kurcalamayı belli eden bir denetim günlüğünü besleyen imza ve şifreleme olayları için denetlenmiş dinleyiciler sunar. Dinleyici sözleşmesi herkese açık olay API’si olduğundan, kendi dinleyicileriniz aynı sağlayıcıda Enterprise dinleyicileriyle birlikte var olabilir.
Ayrıca bkz.
“Ayrıca bkz.” başlıklı bölüm- Eklenti yazımına genel bakış
- Özel yazı tipleri
- Özel yerleşim ve metin yakalama
- Anahtar yönetim hizmeti (KMS) sağlayıcı sözleşmesi
- Hizmet sağlayıcı arabirimi (SPI) kararlılık kuralları
İlgili sözleşmeler ve modüller
“İlgili sözleşmeler ve modüller” başlıklı bölüm- Olay modülü başvurusu — PSR-14 yaşam döngüsü olay taksonomisi ve dağıtıcının iç işleyişi.
- İmzalama sözleşmeleri başvurusu —
SignatureAppliedEventolayının temelindeki sözleşmeler. - SPI kararlılık kuralları — kararlı dağıtıcının ve deneysel yüklerin nasıl sürümlendiği.
- Özel yazı tipleri —
FontLoadedEventolayını kayıt defteri sözleşmesiyle eşleştirir. - Eklenti yazımına genel bakış — herkese açık SPI yüzeyinin tamamı.
Sözlük, bu sayfada kullanılan olay dinleyicisi, olay dağıtıcısı, dinleyici sağlayıcısı ve durdurulabilir olay terimlerini tanımlar. Kurallı tanımlar için yayımlanmış sözlüğe bakın.