مشغّلات الإجراءات ومستمعو الأحداث
لمحة سريعة
قسم بعنوان «لمحة سريعة»يُطلق NextPDF أحداث دورة الحياة عبر نظام في NextPDF\Event متوافق مع توصية معايير PHP رقم 14 (PSR-14). سجِّل مستمعًا، واختر أولوية، وتفاعل عند إنشاء مستند، أو إضافة صفحة، أو تحميل خط، أو تشغيل التوقيع أو التشفير، أو كتابة وحدات البايت، أو بدء الإخراج. أوقف السلسلة فقط عند الحاجة.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/core:^3نظرة مفاهيمية عامة
قسم بعنوان «نظرة مفاهيمية عامة»يتكوّن نظام الأحداث من جزأين عامّين. يربط ListenerProvider كل فئة حدث بقائمة مرتَّبة من المستمعين القابلين للاستدعاء. يمرّ EventDispatcher على تلك القائمة ويستدعي كل مستمع وفق ترتيب الأولوية. كلتا الفئتين final، لذا وسِّع السلوك بالتركيب لا بالتوريث.
تتوافق كلتا الفئتين مع PSR-14 عبر التحقق من السلوك (duck typing). يستخدم EventDispatcher::dispatch() توقيع dispatch() الخاص بـ PSR-14 ويعيد الحدث بعد تشغيل كل مستمع. ويستخدم ListenerProvider::getListenersForEvent() توقيع المزوِّد الخاص بـ PSR-14. لا يتطلب NextPDF حزمة PSR-14. وإذا ثبَّتها مشروعك، فستبقى الواجهات متوافقة.
يهمّ مؤلفي الامتدادات سلوكان:
- الاستماع الشامل (Wildcard). عند تحليل المستمعين، يمرّ المزوِّد على الفئات الأصل للحدث وواجهاته. اربط مستمعًا بالفئة الأساس
AbstractEventلمراقبة كل أحداث دورة الحياة. واربط مستمعًا بواجهة لالتقاط عائلة منها. - الأولوية والانتشار. تعمل الأولوية الأعلى أولًا. وتحافظ الأولويات المتساوية على ترتيب التسجيل. كل حدث يوسِّع
AbstractEventقابل للإيقاف. يمكن لمستمع أن يستدعيstopPropagation()، فيتخطى الموزِّع حينها البقية.
للموزِّع مسار سريع بلا تكلفة. عندما لا يكون أي مستمع مرتبطًا بفئة حدث أو بأي فئة أصل، يعود dispatch() فورًا بعد فحص واحد لـ hasListeners().
أحداث دورة الحياة
قسم بعنوان «أحداث دورة الحياة»| الحدث | مساحة الاسم | يُطلَق عند | الاستقرار |
|---|---|---|---|
DocumentCreatedEvent | NextPDF\Event\Document | انتهاء بناء المستند | تجريبي |
PageAddedEvent | NextPDF\Event\Document | تهيئة صفحة كاملة | تجريبي |
ContentRenderedEvent | NextPDF\Event\Content | عرض المحتوى على صفحة | تجريبي |
FontLoadedEvent | NextPDF\Event\Content | تحميل عائلة خط ونمطه لأول مرة | تجريبي |
SignatureAppliedEvent | NextPDF\Event\Security | تضمين وحدات بايت التوقيع | تجريبي |
EncryptionAppliedEvent | NextPDF\Event\Security | تهيئة التشفير | تجريبي |
PdfSerializedEvent | NextPDF\Event\Writer | اكتمال التسلسل | تجريبي |
DocumentOutputEvent | NextPDF\Event\Document | أوشك تسليم الإخراج على البدء | تجريبي |
الموزِّع، والمزوِّد، وواجهة العلامة، والفئة الأساس stable (منذ 3.0.0). حمولات الأحداث experimental. قد تتغير وسائط مُنشئها وخصائصها للقراءة فقط في إصدار ثانوي. أما إصدارات التصحيح فتضيف فقط. اربط بأسماء خصائص الحمولة مع مراعاة هذا القيد.
واجهة 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 | إعادة ضبط المزوِّد. |
NextPDF\Event\EventDispatcher (مستقر، final):
| الطريقة | تُعيد | الغرض |
|---|---|---|
dispatch(EventInterface $event) | EventInterface | استدعِ المستمعين وفق ترتيب الأولوية، واحترم إيقافات الانتشار، وأعِد الحدث. |
getListenerProvider() | ListenerProvider | الوصول إلى المزوِّد لإضافة مستمعين في وقت التشغيل. |
تستخدم المستندات التي تُطلق الأحداث 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وحدات بايت تنسيق المستندات المحمول (PDF). يقرؤها المحرك مجددًا بعد الإطلاق. إذا غيّرت تلك البايتات، فستحصل على تحكُّم واسع ومخاطرة واسعة. إزاحة بايت خاطئة تُفسد ملف PDF وقد تكسر التوقيع. يُفضَّل الاكتفاء بالمراقبة ما لم تكن تتحكم في النتيجة للحتمية والتواقيع. - بلا موزِّع، بلا أحداث. المستند الذي لم يُضبط له موزِّع عبر
EventAwareDocumentTraitلا يُطلق أي أحداث. هذا هو المسار المقصود بلا تكلفة، وليس خطأً في الإعداد.
الأداء
قسم بعنوان «الأداء»المسار السريع هو فحص واحد لـ hasListeners() عبر سلسلة الفئات الأصل. ومن دون مستمعين، يكون الإطلاق شبه مجاني. يخزّن المزوِّد مؤقتًا قائمة المستمعين المرتَّبة لكل فئة حدث، ولا يمسح ذلك التخزين المؤقت إلا عند تغيّر المستمعين. أبقِ المستمعين غير حاجبين لأنهم يعملون مضمّنين على مسار العرض.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»SignatureAppliedEvent وEncryptionAppliedEvent هما مرسَيا التدقيق. سجِّل مستمعين بأولوية عالية لتدوين التوقيع والتشفير في مخزن مُقاوِم للعبث. لا توقف السلسلة عند حدث أمني ما لم تكن تنوي إسكات المستمعين اللاحقين. فقد يؤدي إيقافها إلى تعطيل خطافات التدقيق اللاحقة بصمت.
المطابقة
قسم بعنوان «المطابقة»لا تطرح هذه الصفحة أي ادعاءات معيارية تتجاوز التوافق مع PSR-14. يقتصر هذا التوافق على التحقق من السلوك (duck-type) ولا يتطلب حزمة PSR-14.
السياق التجاري
قسم بعنوان «السياق التجاري»يأتي NextPDF Enterprise بمستمعين مُدقَّقين لأحداث التوقيع والتشفير يغذّون سجل تدقيق مُقاوِمًا للعبث. ولأن عقد المستمع هو واجهة برمجة تطبيقات الأحداث العمومية (API)، يمكن لمستمعيك الخاصين التعايش مع مستمعي Enterprise على المزوِّد نفسه.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- نظرة عامة على تأليف الامتدادات
- الخطوط المخصصة
- التخطيط المخصص واعتراض النص
- عقد مزوِّد خدمة إدارة المفاتيح (KMS)
- قواعد استقرار واجهة مزوِّد الخدمة (SPI)
العقود والوحدات ذات الصلة
قسم بعنوان «العقود والوحدات ذات الصلة»- مرجع وحدة الأحداث — تصنيف أحداث دورة الحياة وآليات الموزِّع الداخلية وفق PSR-14.
- مرجع عقود التوقيع — العقود وراء
SignatureAppliedEvent. - قواعد استقرار SPI — كيفية إصدار الموزِّع المستقر والحمولات التجريبية.
- الخطوط المخصصة — تقرن
FontLoadedEventبعقد السجل. - نظرة عامة على تأليف الامتدادات — كامل واجهة SPI العمومية.
يُعرِّف المسرد المصطلحات مستمع الأحداث وموزِّع الأحداث ومزوِّد المستمعين والحدث القابل للإيقاف المستخدمة في هذه الصفحة. راجع المسرد المنشور للتعريفات المعتمدة.