ตัวกระตุ้นการทำงานและตัวรับฟังเหตุการณ์
โดยสรุป
หัวข้อที่มีชื่อว่า “โดยสรุป”NextPDF ส่งเหตุการณ์ในวงจรชีวิตผ่านระบบ NextPDF\Event ที่เข้ากันได้กับ PHP Standards Recommendation 14 (PSR-14) คุณสามารถลงทะเบียนตัวรับฟัง เลือกลำดับความสำคัญ และตอบสนองเมื่อมีการสร้างเอกสาร เพิ่มหน้า โหลดฟอนต์ ดำเนินการลงนามหรือเข้ารหัสลับ เขียนไบต์ หรือเริ่มส่งเอาต์พุต หยุดลำดับการทำงานเฉพาะเมื่อจำเป็นเท่านั้น
การติดตั้ง
หัวข้อที่มีชื่อว่า “การติดตั้ง”composer require nextpdf/core:^3ภาพรวมเชิงแนวคิด
หัวข้อที่มีชื่อว่า “ภาพรวมเชิงแนวคิด”ระบบเหตุการณ์มีส่วนสาธารณะสองส่วน ListenerProvider จับคู่คลาสเหตุการณ์แต่ละคลาสกับรายการตัวรับฟัง callable ที่เรียงลำดับแล้ว EventDispatcher วนผ่านรายการนั้นและเรียกตัวรับฟังแต่ละตัวตามลำดับความสำคัญ คลาสทั้งสองเป็น final จึงควรขยายพฤติกรรมด้วยการประกอบแทนการสืบทอดเป็นคลาสย่อย
คลาสทั้งสองตรงกับ PSR-14 โดยใช้ duck typing EventDispatcher::dispatch() ใช้ลายเซ็น dispatch() ของ PSR-14 และคืนค่าเหตุการณ์หลังจากตัวรับฟังทุกตัวทำงานเสร็จ ListenerProvider::getListenersForEvent() ใช้ลายเซ็นของ provider ตาม PSR-14 NextPDF ไม่จำเป็นต้องใช้แพ็กเกจ PSR-14 หากโปรเจกต์ติดตั้งแพ็กเกจนั้นไว้ อินเทอร์เฟซก็ยังสอดคล้องกัน
มีพฤติกรรมสองอย่างที่สำคัญสำหรับผู้พัฒนาส่วนขยาย:
- การรับฟังแบบไวลด์การ์ด ระหว่างการค้นหาตัวรับฟัง provider จะวนผ่านคลาสแม่และอินเทอร์เฟซของเหตุการณ์ ผูกตัวรับฟังกับคลาสฐาน
AbstractEventเพื่อเฝ้าดูทุกเหตุการณ์ในวงจรชีวิต หรือผูกตัวรับฟังกับอินเทอร์เฟซเพื่อจับเหตุการณ์ทั้งตระกูล - ลำดับความสำคัญและการแพร่กระจาย ลำดับความสำคัญที่สูงกว่าจะทำงานก่อน ลำดับความสำคัญที่เท่ากันจะคงลำดับการลงทะเบียนไว้ ทุกเหตุการณ์ที่ขยายจาก
AbstractEventสามารถหยุดได้ ตัวรับฟังสามารถเรียกstopPropagation()ได้ หลังจากนั้นตัวจัดส่งจะข้ามตัวรับฟังที่เหลือ
ตัวจัดส่งมีเส้นทางด่วนแบบไม่มีต้นทุน เมื่อไม่มีตัวรับฟังผูกกับคลาสเหตุการณ์หรือคลาสแม่ใดๆ dispatch() จะคืนค่าทันทีหลังจากตรวจสอบ hasListeners() เพียงครั้งเดียว
เหตุการณ์ในวงจรชีวิต
หัวข้อที่มีชื่อว่า “เหตุการณ์ในวงจรชีวิต”| เหตุการณ์ | เนมสเปซ | ส่งเมื่อ | เสถียรภาพ |
|---|---|---|---|
DocumentCreatedEvent | NextPDF\Event\Document | สร้างเอกสารเสร็จสิ้น | experimental |
PageAddedEvent | NextPDF\Event\Document | กำหนดค่าเริ่มต้นของหน้าเสร็จสมบูรณ์ | experimental |
ContentRenderedEvent | NextPDF\Event\Content | เรนเดอร์เนื้อหาไปยังหน้าแล้ว | experimental |
FontLoadedEvent | NextPDF\Event\Content | โหลดตระกูลฟอนต์และสไตล์เป็นครั้งแรก | experimental |
SignatureAppliedEvent | NextPDF\Event\Security | มีการฝังไบต์ของลายเซ็น | experimental |
EncryptionAppliedEvent | NextPDF\Event\Security | มีการกำหนดค่าการเข้ารหัสลับ | experimental |
PdfSerializedEvent | NextPDF\Event\Writer | ทำให้เป็นอนุกรมเสร็จสมบูรณ์ | experimental |
DocumentOutputEvent | NextPDF\Event\Document | กำลังจะเริ่มส่งมอบเอาต์พุต | experimental |
ตัวจัดส่ง, provider, อินเทอร์เฟซตัวบ่งชี้ และคลาสฐานเป็น stable (ตั้งแต่ 3.0.0) เพย์โหลดของเหตุการณ์เป็น experimental อาร์กิวเมนต์ตัวสร้างและคุณสมบัติแบบ readonly ของเพย์โหลดอาจเปลี่ยนแปลงได้ในรุ่นย่อย รุ่นแพตช์มีเฉพาะการเพิ่มเติมเท่านั้น ให้ผูกกับชื่อคุณสมบัติของเพย์โหลดโดยคำนึงถึงข้อจำกัดนี้
พื้นผิว API
หัวข้อที่มีชื่อว่า “พื้นผิว API”NextPDF\Event\ListenerProvider (เสถียร, final):
| เมท็อด | คืนค่า | วัตถุประสงค์ |
|---|---|---|
addListener(string $eventClass, callable $listener, int $priority = 0) | void | ลงทะเบียนตัวรับฟัง ลำดับความสำคัญที่สูงกว่าจะทำงานก่อน โยน InvalidConfigException เมื่อคลาสว่าง |
getListenersForEvent(EventInterface $event) | list<callable> | ค้นหาตัวรับฟัง รวมถึงการลงทะเบียนบนคลาสแม่และอินเทอร์เฟซ |
hasListeners(string $eventClass) | bool | ตรวจสอบลำดับชั้นของคลาสโดยไม่เพิ่มต้นทุน |
getListenerCount(string $eventClass) | int | นับเฉพาะการลงทะเบียนโดยตรงเท่านั้น |
clearListeners() | void | รีเซ็ต provider |
NextPDF\Event\EventDispatcher (เสถียร, final):
| เมท็อด | คืนค่า | วัตถุประสงค์ |
|---|---|---|
dispatch(EventInterface $event) | EventInterface | เรียกใช้ตัวรับฟังตามลำดับความสำคัญ เคารพการหยุดแพร่กระจาย และคืนค่าเหตุการณ์ |
getListenerProvider() | ListenerProvider | เข้าถึง provider เพื่อเพิ่มตัวรับฟังระหว่างรันไทม์ |
เอกสารที่ส่งเหตุการณ์ใช้ NextPDF\Event\EventAwareDocumentTrait เมท็อด setEventDispatcher() เชื่อมตัวจัดส่งเข้ากับเอกสารหนึ่งฉบับ เมื่อไม่มีตัวจัดส่ง ตัวช่วยส่งเหตุการณ์ทุกตัวจะไม่ทำงานใดๆ
ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — เริ่มต้นใช้งานอย่างรวดเร็ว”<?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);ตัวอย่างโค้ด — การใช้งานจริง
หัวข้อที่มีชื่อว่า “ตัวอย่างโค้ด — การใช้งานจริง”ตัวรับฟังการตรวจสอบสำหรับการใช้งานจริงนี้ใช้ลำดับความสำคัญสูงเพื่อให้ทำงานก่อน เขียนล็อกแบบมีโครงสร้าง และเพิ่มตัวรับฟังแบบดักจับทั้งหมดบนคลาสฐานเพื่อให้ครอบคลุมครบถ้วน
<?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); }}กรณีขอบเขตและข้อควรระวัง
หัวข้อที่มีชื่อว่า “กรณีขอบเขตและข้อควรระวัง”- คลาส final
EventDispatcherและListenerProviderเป็นfinalให้ใช้การประกอบกับคลาสเหล่านี้ อย่าสืบทอดเป็นคลาสย่อย - คลาสเหตุการณ์ว่างจะโยนข้อยกเว้น
addListener('', ...)จะโยนInvalidConfigExceptionให้ส่งค่าคงที่แบบ class-string เสมอ - ต้นทุนของไวลด์การ์ด ตัวรับฟังบน
AbstractEventจะทำงานสำหรับทุกเหตุการณ์ กำหนดให้ตัวรับฟังแบบดักจับทั้งหมดมีลำดับความสำคัญต่ำ และทำให้ตัวรับฟังทำงานเบา - การเปลี่ยนแปลงเอาต์พุต
DocumentOutputEventมีไบต์ Portable Document Format (PDF) มาด้วย หลังจากส่งแล้ว เอนจินจะอ่านไบต์เหล่านั้นกลับมา หากคุณเปลี่ยนไบต์เหล่านั้น คุณจะได้อำนาจควบคุมสูง แต่ความเสี่ยงก็สูงตาม ออฟเซ็ตไบต์ที่ผิดจะทำให้ PDF เสียหายและอาจทำให้ลายเซ็นเสียได้ ควรเลือกเพียงการเฝ้าสังเกต เว้นแต่คุณเป็นผู้รับผิดชอบความกำหนดได้แน่นอนของเอาต์พุตและลายเซ็นเอง - ไม่มีตัวจัดส่ง ไม่มีเหตุการณ์ เอกสารที่ไม่มีการตั้งตัวจัดส่งผ่าน
EventAwareDocumentTraitจะไม่ส่งเหตุการณ์ใด นี่เป็นเส้นทางแบบไม่มีต้นทุนที่ออกแบบไว้ ไม่ใช่ข้อผิดพลาดในการตั้งค่า
ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”เส้นทางด่วนคือการตรวจสอบ hasListeners() บนสายลำดับคลาสแม่เพียงครั้งเดียว เมื่อไม่มีตัวรับฟัง การส่งแทบไม่มีต้นทุน provider จะแคชรายการตัวรับฟังที่เรียงลำดับแล้วต่อคลาสเหตุการณ์ และล้างแคชนั้นเฉพาะเมื่อมีการเปลี่ยนแปลงตัวรับฟัง ควรทำให้ตัวรับฟังไม่บล็อกการทำงาน เพราะตัวรับฟังทำงานแบบอินไลน์บนเส้นทางการเรนเดอร์
หมายเหตุด้านความปลอดภัย
หัวข้อที่มีชื่อว่า “หมายเหตุด้านความปลอดภัย”SignatureAppliedEvent และ EncryptionAppliedEvent เป็นจุดเชื่อมต่อสำหรับการตรวจสอบ ลงทะเบียนตัวรับฟังลำดับความสำคัญสูงเพื่อบันทึกการลงนามและการเข้ารหัสลับลงในที่จัดเก็บแบบตรวจพบการดัดแปลงได้ อย่าหยุดลำดับการทำงานบนเหตุการณ์ด้านความปลอดภัย เว้นแต่คุณตั้งใจจะปิดการทำงานของตัวรับฟังลำดับถัดไป การหยุดลำดับการทำงานอาจปิดการทำงานของฮุกการตรวจสอบที่ตามมาอย่างเงียบๆ
ความสอดคล้อง
หัวข้อที่มีชื่อว่า “ความสอดคล้อง”หน้านี้ไม่ได้กล่าวอ้างเชิงบรรทัดฐานใดๆ นอกเหนือจากความเข้ากันได้กับ PSR-14 ความเข้ากันได้นั้นเป็นแบบ duck-type เท่านั้นและไม่จำเป็นต้องใช้แพ็กเกจ PSR-14
บริบทเชิงพาณิชย์
หัวข้อที่มีชื่อว่า “บริบทเชิงพาณิชย์”NextPDF Enterprise มาพร้อมตัวรับฟังที่ได้รับการตรวจสอบสำหรับเหตุการณ์ลายเซ็นและการเข้ารหัสลับ ซึ่งป้อนข้อมูลให้ล็อกการตรวจสอบแบบตรวจพบการดัดแปลงได้ เนื่องจากสัญญาของตัวรับฟังอยู่ที่ application programming interface (API) ของเหตุการณ์สาธารณะ ตัวรับฟังของคุณเองจึงสามารถใช้งานร่วมกับตัวรับฟังของ Enterprise บน provider เดียวกันได้
ดูเพิ่มเติม
หัวข้อที่มีชื่อว่า “ดูเพิ่มเติม”- ภาพรวมการพัฒนาส่วนขยาย
- ฟอนต์ที่กำหนดเอง
- เค้าโครงที่กำหนดเองและการดักจับข้อความ
- สัญญาผู้ให้บริการ Key Management Service (KMS)
- กฎเสถียรภาพของ Service Provider Interface (SPI)
สัญญาและโมดูลที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “สัญญาและโมดูลที่เกี่ยวข้อง”- เอกสารอ้างอิงโมดูล Event — อนุกรมวิธานของเหตุการณ์ในวงจรชีวิตตาม PSR-14 และกลไกภายในของตัวจัดส่ง
- เอกสารอ้างอิงสัญญาการลงนาม — สัญญาที่อยู่เบื้องหลัง
SignatureAppliedEvent - กฎเสถียรภาพของ SPI — วิธีกำหนดเวอร์ชันของตัวจัดส่งที่เสถียรและเพย์โหลดแบบ experimental
- ฟอนต์ที่กำหนดเอง — จับคู่
FontLoadedEventกับสัญญาของรีจิสทรี - ภาพรวมการพัฒนาส่วนขยาย — พื้นผิว SPI สาธารณะทั้งหมด
อภิธานศัพท์อธิบายคำว่า event listener, event dispatcher, listener provider และ stoppable event ที่ใช้ในหน้านี้ โปรดดูคำนิยามมาตรฐานในอภิธานศัพท์ที่เผยแพร่แล้ว