Статьи

Как использовать диспетчер событий Symfony для PHP

Сегодня мы узнаем, как использовать компонент диспетчера событий Symfony, который позволяет создавать события и прослушиватели в ваших приложениях PHP. Таким образом, различные компоненты вашего приложения могут общаться друг с другом с помощью слабосвязанного кода.

Возможно, вы знакомы с шаблоном наблюдателя событий, который позволяет вам определять прослушиватели для сгенерированных системой событий, чтобы они выполнялись при запуске события. Аналогичным образом, компонент Symfony EventDispatcher позволяет вам настроить систему, в которой вы можете создавать собственные события и прослушиватели. Таким образом, вы позволяете компонентам в вашем приложении реагировать, если что-то происходит в системе.

Фактически, компонент диспетчера событий предоставляет три элемента, которые вы можете построить вокруг своей архитектуры приложения. :   событие, слушатель и диспетчер. Вся система управляется классом диспетчера, который вызывает события в соответствующих точках приложения и вызывает слушателей, связанных с этими событиями.

Предположим, вы хотите разрешить другим компонентам в вашем приложении реагировать при очистке кэша. В этом случае вам необходимо определить событие очистки кэша в первую очередь. После очистки кэша вы можете использовать диспетчер, чтобы вызвать событие очистки кэша, и это уведомляет всех слушателей, которые слушают это событие. Это дает слушателям возможность очищать кэши компонентов.

В этой статье мы рассмотрим основы компонента диспетчера событий. Мы начнем с установки и настройки, а также создадим несколько реальных примеров, чтобы продемонстрировать все концепции, упомянутые выше.

В этом разделе мы собираемся установить компонент диспетчера событий. Я предполагаю, что вы уже установили Composer в своей системе, потому что он нам понадобится для установки компонента EventDispatcher.

После того, как вы установили Composer, продолжайте и установите компонент EventDispatcher, используя следующую команду.

1
$composer require symfony/event-dispatcher

Это должно было создать файл composer.json , который должен выглядеть следующим образом:

1
2
3
4
5
{
    «require»: {
        «symfony/event-dispatcher»: «^4.1»
    }
}

Давайте далее отредактируем файл composer.json, чтобы он выглядел следующим образом:

01
02
03
04
05
06
07
08
09
10
11
{
    «require»: {
        «symfony/event-dispatcher»: «^4.1»
    },
    «autoload»: {
         «psr-4»: {
             «EventDispatchers\\»: «src»
         },
         «classmap»: [«src»]
     }
}

Как только мы добавили новую запись в classmap, продолжите и обновите автозагрузчик Composer, выполнив следующую команду.

1
$composer dump -o

Теперь вы можете использовать пространство имен EventDispatchers для автозагрузки классов в каталоге src .

Так что это часть установки, но как вы должны ее использовать? Фактически, это просто вопрос включения файла autoload.php, созданного Composer, в ваше приложение, как показано в следующем фрагменте.

1
2
3
4
5
<?php
require_once ‘./vendor/autoload.php’;
 
// application code
?>

В этом разделе мы рассмотрим пример, который демонстрирует, как можно создать пользовательское событие и настроить прослушиватель для этого события.

Для начала создайте файл src / Events / DemoEvent.php со следующим содержимым.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?php
namespace EventDispatchers\Events;
 
use Symfony\Component\EventDispatcher\Event;
 
class DemoEvent extends Event
{
    const NAME = ‘demo.event’;
 
    protected $foo;
 
    public function __construct()
    {
        $this->foo = ‘bar’;
    }
 
    public function getFoo()
    {
        return $this->foo;
    }
}

Наш пользовательский класс DemoEvent расширяет базовый класс Event компонента EventDispatcher. Константа NAME содержит имя нашего пользовательского события demo.event . Он используется, когда вы хотите настроить прослушиватель для этого события.

Далее, давайте создадим класс слушателя src / Listeners / DemoListener.php со следующим содержимым.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<?php
namespace EventDispatchers\Listeners;
 
use Symfony\Component\EventDispatcher\Event;
 
class DemoListener
{
    public function onDemoEvent(Event $event)
    {
      // fetch event information here
      echo «DemoListener is called!\n»;
      echo «The value of the foo is: «.$event->getFoo().»\n»;
    }
}

Класс DemoListener реализует метод onDemoEvent который запускается, когда система отправляет событие DemoEvent . Конечно, это еще не произойдет автоматически, поскольку нам нужно зарегистрировать прослушиватель DemoListener для прослушивания события demo.event с использованием класса EventDispatcher.

Пока что мы создали классы событий и слушателей. Далее мы увидим, как связать все эти части вместе.

Давайте создадим файл basic_example.php со следующим содержимым.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?php
// basic_example.php
 
require_once ‘./vendor/autoload.php’;
use Symfony\Component\EventDispatcher\EventDispatcher;
use EventDispatchers\Events\DemoEvent;
use EventDispatchers\Listeners\DemoListener;
 
// init event dispatcher
$dispatcher = new EventDispatcher();
 
// register listener for the ‘demo.event’ event
$listener = new DemoListener();
$dispatcher->addListener(‘demo.event’, array($listener, ‘onDemoEvent’));
 
// dispatch
$dispatcher->dispatch(DemoEvent::NAME, new DemoEvent());

Класс EventDispatcher является наиболее важным элементом в компоненте EventDispatcher — он позволяет привязывать слушателей к событиям, которые они хотят прослушивать. Мы использовали метод addListener класса EventDispatcher для прослушивания события demo.event .

Первым аргументом метода addListener является имя события, а вторым аргументом является вызываемый PHP, который запускается при отправке зарегистрированного события. В нашем случае мы предоставили объект DemoListener в качестве прослушивателя вместе с методом onDemoEvent .

1
$dispatcher->addListener(‘demo.event’, array($listener, ‘onDemoEvent’));

Наконец, мы использовали метод dispatch класса EventDispatcher для отправки события demo.event .

1
$dispatcher->dispatch(DemoEvent::NAME, new DemoEvent());

Когда вы запускаете файл basic_example.php , он должен выдать следующий вывод.

1
2
3
$php basic_example.php
DemoListener is called!
The value of the foo is: bar

Как и ожидалось, onDemoEvent метод DemoListener класса DemoListener , который, в свою очередь, вызывает метод DemoEvent класса DemoEvent для получения информации, связанной с событием.

В предыдущем разделе мы создали пример, демонстрирующий, как создать пользовательское событие и пользовательский прослушиватель. Мы также обсудили, как привязать слушателя к определенному событию, используя класс EventDispatcher .

Это был простой пример, так как мы хотели настроить слушателя только для одного события. С другой стороны, если вы хотите настроить прослушиватели для нескольких событий или хотите логически сгруппировать логику обработки событий в одном классе, вам следует рассмотреть возможность использования подписчиков событий, поскольку они позволяют хранить все в одном месте.

В этом разделе мы рассмотрим пример, который был создан в предыдущем разделе.

Первое, что нам нужно сделать, это создать класс подписчика, который реализует интерфейс EventSubscriberInterface . Создайте класс src / Subsribers / DemoSubscriber.php, как показано в следующем фрагменте.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
namespace EventDispatchers\Subscribers;
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use EventDispatchers\Events\DemoEvent;
 
class DemoSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            DemoEvent::NAME => ‘onDemoEvent’,
        );
    }
 
    public function onDemoEvent(DemoEvent $event)
    {
      // fetch event information here
      echo «DemoListener is called!\n»;
      echo «The value of the foo is :».$event->getFoo().»\n»;
    }
}

Поскольку класс DemoSubscriber реализует интерфейс DemoSubscriber , он должен реализовывать метод getSubscribedEvents . Метод getSubscribedEvents должен возвращать массив событий, на которые вы хотите подписаться. Вам нужно указать имя события в ключе массива и имя метода в значении массива, которое вызывается при запуске события.

Последнее, что нужно, — реализовать метод слушателя в том же классе. В нашем случае нам нужно реализовать метод onDemoEvent , и мы уже сделали это.

Пришло время протестировать нашего подписчика! Давайте быстро создадим файл subscriber_example.php со следующим содержимым.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?php
require_once ‘./vendor/autoload.php’;
use Symfony\Component\EventDispatcher\EventDispatcher;
use EventDispatchers\Subscribers\DemoSubscriber;
use EventDispatchers\Events\DemoEvent;
 
// init event dispatcher
$dispatcher = new EventDispatcher();
 
// register subscriber
$subscriber = new DemoSubscriber();
$dispatcher->addSubscriber($subscriber);
 
// dispatch
$dispatcher->dispatch(DemoEvent::NAME, new DemoEvent());

Вам необходимо использовать метод addSubscriber класса EventDispatcher чтобы подписать своего пользовательского подписчика, а класс EventDispatcher обрабатывает все остальное. Он выбирает события для подписки из метода getSubscribedEvents и устанавливает прослушиватели для этих событий. Кроме того, все то же самое, и оно должно работать, как и ожидалось, без сюрпризов.

Давайте проверим это!

1
2
3
$php subscriber_example.php
DemoListener is called!
The value of the foo is: bar

И это был подписчик событий в вашем распоряжении! Это также подводит нас к концу этой статьи.

Сегодня мы исследовали компонент диспетчера событий Symfony, который позволяет вам настраивать события и прослушиватели в ваших PHP-приложениях. Используя эту библиотеку, вы можете создать слабо связанную систему, которая позволит компонентам вашего приложения легко взаимодействовать друг с другом.

Не стесняйтесь делиться своими мыслями и вопросами, используя форму ниже!