دليل Symfony/EventDispatcher PHP الشامل مع أمثلة تطبيقية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة عن نظام الأحداث في Symfony/EventDispatcher

نظام الأحداث (Event Dispatcher) هو أحد المكونات الأساسية في بيئة Symfony، وهو يطبق نمطي التصميم "المراقب" (Observer) و"الوسيط" (Mediator). توفر مكتبة symfony/event-dispatcher آلية خفيفة الوزن لكنها قوية لبناء تطبيقات ذات بنية غير مترابطة (loosely coupled). بدلاً من ربط المكونات بشكل صلب باستدعاءات مباشرة للدوال، يمكنك "إطلاق" الأحداث، وتقوم أي أجزاء مهتمة من التطبيق (المستمعون/المشتركون) بالتفاعل معها. هذا يبسط بشكل جذري عملية توسيع الوظائف والاختبار وصيانة الكود.

لماذا تحتاج هذا؟ تخيل أنك تريد إضافة تسجيل لكل إجراء يقوم به المستخدم، وإرسال إشعار بريد إلكتروني بعد التسجيل، وتحديث الذاكرة المؤقتة (cache) بعد تعديل البيانات. بدون نظام الأحداث، ستضطر إلى إضافة استدعاءات الخدمات المناسبة مباشرة داخل دوال المتحكم (Controller) أو النموذج (Model). هذا يخلق ارتباطًا صلبًا (coupling) ويجعل الكود "هشًا". مع EventDispatcher، يمكنك ببساطة إطلاق حدث UserRegistered، ويقوم مستمعون منفصلون (مسجل، مرسل بريد، محدث ذاكرة) بالاشتراك في هذا الحدث وتنفيذ مهامهم. إضافة وظيفة جديدة يقتصر على كتابة مستمع جديد، دون تغيير الكود الموجود.

تُستخدم هذه المكتبة ليس فقط في إطار العمل الكامل Symfony، بل أيضًا في الأطر الصغيرة (Silex، ولارافيل لها تطبيقها الخاص لكن المفهوم واحد)، وكذلك في أي مشروع PHP يحتاج إلى نظام خطافات (hooks) وإضافات (plugins) مرن. وهي تعتبر المعيار الفعلي (de-facto) للبرمجة الموجهة بالأحداث في PHP.

التثبيت

يتم التثبيت عبر Composer، مدير الحزم القياسي لـ PHP. افتح الطرفية (Terminal) في جذر مشروعك ونفذ الأمر التالي:

composer require symfony/event-dispatcher

إذا كنت تخطط لاستخدام حاوية حقن التبعيات (Dependency Injection) والتسجيل التلقائي للمستمعين، يُنصح أيضًا بتثبيت حزمة العمل مع DependencyInjection (عادة ما تأتي مع Symfony Framework). للاستخدام المستقل، يكفي تثبيت symfony/event-dispatcher فقط.

بداية سريعة: مثال عملي مصغر

لنقم بإنشاء نظام بسيط: سنقوم بإطلاق حدث "order.placed" (تم تقديم الطلب) والاستماع إليه.

<?php
// 1. تحميل أداة التحميل التلقائي من Composer
require_once 'vendor/autoload.php';

use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\GenericEvent;

// 2. إنشاء الموزع (Dispatcher)
$dispatcher = new EventDispatcher();

// 3. إضافة مستمع (دالة مجهولة) للحدث 'order.placed'
$dispatcher->addListener('order.placed', function (GenericEvent $event) {
    $orderData = $event->getSubject();
    echo "المستمع 1: تم تقديم الطلب رقم {$orderData['id']}. المبلغ: {$orderData['total']}\n";
});

// 4. إنشاء حدث وتمرير البيانات إليه
$event = new GenericEvent(['id' => 123, 'total' => 2500.00]);

// 5. إطلاق (توزيع) الحدث
$dispatcher->dispatch($event, 'order.placed');

// الإخراج: المستمع 1: تم تقديم الطلب رقم 123. المبلغ: 2500

يوضح هذا المثال الآلية الأساسية: إنشاء الموزع، تسجيل المستمع، وإرسال الحدث. لاحظ أن المستمع يتلقى كائن الحدث الذي يمكن استخراج أي بيانات منه.

الدوال والفئات الرئيسية

دعنا نستعرض 8 عناصر أساسية في المكتبة تغطي 90% من حالات الاستخدام.

1. EventDispatcher::addListener()

التوقيع: addListener(string $eventName, callable $listener, int $priority = 0): void

الوظيفة: تسجيل مستمع (دالة قابلة للاستدعاء) لاسم حدث محدد. يمكن تحديد أولوية: كلما زاد الرقم، تم استدعاء المستمع مبكرًا.

توصيات