İçeriğe geç

Event: PSR-14 yaşam döngüsü olayı sınıflandırması

Event modülü, PDF üretiminin her aşamasında tipli yaşam döngüsü olayları gönderir. Dinleyiciler, motorun iç yapısını değiştirmeden bir belgeyi gözlemleyebilir veya dönüştürebilir. Dağıtıcı, PHP Standards Recommendation 14 (PSR-14) standardını izler; bu nedenle mevcut PSR-14 araçlarıyla uyumluluk korunur.

Terminal window
composer require nextpdf/core:^3

Event modülü, core paketiyle birlikte gelir. Ek bağımlılığı yoktur: EventInterface ve StoppableEventInterface türleri, psr/event-dispatcher paketini gerektirmeden PSR-14 sözleşmelerini karşılar.

Modül üç bölümden oluşur: bir dağıtıcı, bir dinleyici sağlayıcı ve sabit bir yaşam döngüsü olayı sınıfları kümesi.

EventDispatcher bir EventInterface örneği alır, eşleşen dinleyiciler için ListenerProvider öğesini sorgular ve her birini öncelik sırasına göre çağırır. dispatch() yöntemi aynı olay nesnesini döndürür. Bir dinleyici, motorun olaya yerleştirdiği durumu okuyabilir ve motorun daha sonra okuyacağı durumu geri yazabilir. Bu davranış, PSR-14 dağıtıcı modeliyle örtüşür.

ListenerProvider, bir olay sınıfını öncelik sırasına göre düzenlenmiş çağrılabilirler listesiyle eşler. Kayıt örnek kapsamındadır ve statik durum içermez; böylece bir işçi süreci kendi sağlayıcı örneklerini tutabilir. Sağlayıcı, olay sınıfı ağacında ve ilgili arabirimlerde de dolaşır. AbstractEvent üzerinde kayıtlı bir dinleyici, her yaşam döngüsü olayını görür. Bir arabirim üzerinde kayıtlı bir dinleyici, onu uygulayan her olayı görür.

StoppableEventInterface, yayılım denetimi ekler. Bir dinleyici stopPropagation() çağırabilir; dağıtıcı da o döngüde sonraki dinleyicileri çağırmayı durdurur. Durdurulabilir olay, dinleyici zincirini durdurma yolunu kendi üzerinde taşıyan özel bir olaydır. PSR-14, durdurulabilir olaylar için aynı modeli kullanır (PSR-14 psr_14_event#x4). AbstractEvent, arabirimi StoppableEventTrait aracılığıyla uygular; böylece her yaşam döngüsü olayı varsayılan olarak durdurulabilir.

Dağıtıcının ek yükü sıfıra yakın bir hızlı yolu vardır. Olay sınıfında veya herhangi bir atasında dinleyici olup olmadığını denetler. Hiçbiri yoksa hasListeners() false döndürür ve dispatch() hemen geri döner. Dinleyicisi olmayan bir belgenin maliyeti, her yaşam döngüsü noktası başına bir boole denetimiyle sınırlıdır.

EventAwareDocumentTrait, tümleştirme noktasıdır. İsteğe bağlı bir EventDispatcher tutar ve korumalı dağıtım yardımcılarını açığa çıkarır. Document sınıfı, bu yardımcıları her yaşam döngüsü noktasında çağırır. Dağıtıcı ayarlanmadığında, her yardımcı işlemsizdir.

Yaşam döngüsü sınıflandırması şu olayları kapsar:

OlayAd alanıTetiklenme
DocumentCreatedEventEvent\DocumentBelge tamamen oluşturulduktan sonra
PageAddedEventEvent\DocumentSayfa başlatıldıktan sonra
ContentRenderedEventEvent\ContentSayfaya HTML veya metin içeriği işlendikten sonra
FontLoadedEventEvent\ContentYazı tipi bir kayda ayrıştırıldığında
EncryptionAppliedEventEvent\SecurityŞifreleme parametreleri yapılandırıldıktan sonra
SignatureAppliedEventEvent\SecurityBir imza gömüldükten sonra
PdfSerializedEventEvent\WriterSerileştirmeden sonra, çıktı teslimatından önce
DocumentOutputEventEvent\DocumentPDF baytları hedefe ulaşmadan önce
SimgeTürTemel üyeler
NextPDF\Event\EventInterfacearabirimgetEventName(): non-empty-string
NextPDF\Event\StoppableEventInterfacearabirimisPropagationStopped(): bool
NextPDF\Event\StoppableEventTraittraitisPropagationStopped(), stopPropagation()
NextPDF\Event\AbstractEventsoyut sınıfgetEventName(); uyguladığı arabirim: StoppableEventInterface
NextPDF\Event\EventDispatcherfinal sınıfdispatch(EventInterface): EventInterface, getListenerProvider()
NextPDF\Event\ListenerProviderfinal sınıfaddListener(), getListenersForEvent(), hasListeners(), getListenerCount(), clearListeners()
NextPDF\Event\EventAwareDocumentTraittraitsetEventDispatcher(), getEventDispatcher()
NextPDF\Event\Document\DocumentCreatedEventfinal sınıf$document, $config
NextPDF\Event\Document\PageAddedEventfinal sınıf$document, $pageIndex, $pageSize, $orientation
NextPDF\Event\Document\DocumentOutputEventfinal sınıfgetPdfData(), setPdfData(), getByteSize(), $filename, $destination
NextPDF\Event\Content\ContentRenderedEventfinal sınıf$document, $pageIndex, $contentType, $content
NextPDF\Event\Content\FontLoadedEventfinal sınıf$family, $style, $fontType, $filePath
NextPDF\Event\Security\EncryptionAppliedEventfinal sınıf$document, $algorithm, $allowPrint, $allowCopy, $allowModify
NextPDF\Event\Security\SignatureAppliedEventfinal sınıf$document, $signatureLevel, $signerName, $reason, $location
NextPDF\Event\Writer\PdfSerializedEventfinal sınıf$byteSize, $objectCount, $pageCount, $pdfVersion, $isLinearized, $isEncrypted

addListener(), olay sınıfı dizesi boşsa NextPDF\Exception\InvalidConfigException fırlatır.

Bir dinleyici kaydedin, ardından bir yaşam döngüsü olayı gönderin.

<?php
declare(strict_types=1);
use NextPDF\Event\Document\PageAddedEvent;
use NextPDF\Event\EventDispatcher;
use NextPDF\Event\ListenerProvider;
$provider = new ListenerProvider();
$provider->addListener(
PageAddedEvent::class,
static function (PageAddedEvent $event): void {
\printf("Page %d added (%s)\n", $event->pageIndex, $event->pageSize->name);
},
);
$dispatcher = new EventDispatcher($provider);

Dağıtıcı eklendikten sonra Document sınıfı dağıtım yardımcılarını dahili olarak çağırır; dağıtıcı setEventDispatcher() aracılığıyla iliştirilir.

Dağıtıcıyı bir belgeye bağlayın, dinleyici önceliğini ayarlayın ve geçit dinleyicisinden yayılımı durdurun.

<?php
declare(strict_types=1);
use NextPDF\Event\Document\DocumentOutputEvent;
use NextPDF\Event\Document\PageAddedEvent;
use NextPDF\Event\EventDispatcher;
use NextPDF\Event\ListenerProvider;
$provider = new ListenerProvider();
// Higher priority runs first. A licensing gate observes every page.
$provider->addListener(
PageAddedEvent::class,
static function (PageAddedEvent $event): void {
if ($event->pageIndex >= 100) {
// Stop later page listeners for this dispatch cycle.
$event->stopPropagation();
}
},
priority: 100,
);
// Last-chance hook: replace the PDF bytes before delivery.
$provider->addListener(
DocumentOutputEvent::class,
static function (DocumentOutputEvent $event): void {
$optimized = \gzencode($event->getPdfData(), 0);
if ($optimized !== false) {
$event->setPdfData($optimized);
}
},
);
$dispatcher = new EventDispatcher($provider);
// Pass $dispatcher to a Document via setEventDispatcher($dispatcher).
  • Joker karakterli kayıt, sınıf hiyerarşisini kullanır. AbstractEvent üzerindeki bir dinleyici, her olay onu genişlettiği için her yaşam döngüsü olayını alır. Yalnızca tek bir olay istediğinizde, dinleyicileri somut sınıflarla sınırlandırın.
  • Dinleyici önceliği, en yüksek önce olacak şekilde sıralanır. Eşit öncelikler ekleme sırasını korur (kararlı sıralama).
  • stopPropagation() yalnızca geçerli dağıtım döngüsünü durdurur. Bir sonraki gönderilen olay, yeni bir döngü başlatır.
  • Yeni bir üst sınıf veya arabirim kaydı, birkaç olay sınıfı için çözümlemeyi değiştirebileceğinden, sıralanmış dinleyici önbelleği herhangi bir addListener() çağrısında geçersiz kılınır.
  • $document, belge kapsamındaki olaylarda object olarak türlenir; Document sınıfı olarak değil. Bu, Event modülünü katı bir Core bağımlılığına bağlamamak içindir.
  • DocumentOutputEvent::setPdfData() boş olmayan bir dize bekler. Yükü boş bir dizeyle değiştirmek geçersiz bir belge üretir.
  • Dağıtım yardımcıları, EventAwareDocumentTrait üzerinde bir dağıtıcı ayarlanana kadar işlemsizdir; bu nedenle dinleyicisiz çalıştırmalar ölçülebilir bir maliyet eklemez.

Dinleyici olmadığında dağıtım, bir yaprak olay sınıfı için O(1)‘dir: bir hasListeners() boole denetimi ve ardından anında geri dönüş. Dinleyiciler varsa, getListenersForEvent() olay soyağacında bir kez dolaşır, toplanan girdileri sıralar ve sonraki değişikliğe kadar sıralanmış listeyi olay sınıfı başına önbelleğe alır. Bu nedenle aynı sınıf için yinelenen dağıtım, eşleşen k dinleyici üzerinden O(k)‘dir. Bu başvuru sayfası için varsayılan performance_budget değeri wall_ms: 1500, peak_mb: 64 şeklindedir.

Dinleyiciler, üretim hattı içinde çağıran tarafla aynı ayrıcalıklarla çalışır. Dinleyici kodunu güvenilir kod olarak değerlendirin. DocumentOutputEvent, nihai PDF ikili verisini açığa çıkarır ve bir dinleyicinin onu değiştirmesine izin verir. Denetim veya bütünlük dinleyicisi, baytları dönüştüren herhangi bir dinleyiciden önce çalışmalıdır. Daha yüksek bir öncelik kullanın. Güvenlik kapsamındaki olaylar (EncryptionAppliedEvent, SignatureAppliedEvent), denetim günlüğü için uygulanan parametreleri bildirir. Bunlar, kriptografik sonucu değiştirmez.

BelirtimMaddeKonu
PSR-14 (PHP-FIG)psr_14_event#x4Durdurulabilir olay, sonraki dinleyicileri durdurur

Hem dispatch() imzası hem dinleyici-sağlayıcı ayrımı hem de durdurulabilir olay modeli PSR-14 standardını izler. NextPDF kendi EventInterface ve StoppableEventInterface arabirimlerini bildirir. Paketin PSR-14 çalışma zamanı bağımlılığı yoktur, ancak duck-type uyumluluğunu korur.

  • /modules/core/contracts/ — genel arabirim yüzeyi
  • /modules/core/observability/ — telemetri ve metrik kancaları
  • /modules/core/audit/ — denetim izi tümleştirmesi
  • /modules/core/config/Config, iletildiği olay: DocumentCreatedEvent
  • /modules/core/exception/InvalidConfigException, fırlatıldığı çağrı: addListener()

Sözlük: PSR-14 · durdurulabilir olay · dinleyici sağlayıcı