Symfony EventDispatcher

Первым делом - EventDispatcher это реализация паттерна Диспетчер (можете представить себе телефонного диспетчера или диспетчера в аэропорту).

Описание Один системный компонент назначается диспетчером и управляет запуском и завершением других процессов системы и координирует эти процессы. Процессы могут протекать параллельно (в нашем случае последовадтельно, т.к. PHP).
Рекомендации Применяется в системах, в которых необходимо организовать параллельные процессы, но может использоваться также и для последовательных систем, в которых- управляющая программа вызывает отдельные подсистемы в зависимости от значений некоторых переменных состояния.
Пример Можно использовать в системах реального времени, где нет чересчур строгих временных ограничений (в так называемых "мягких" системах реального времени).

Давайте посмотрим, каким классом реализуется диспетчер событий:

$ app/console container:debug | grep dispatcher

debug.event_dispatcher      Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher
event_dispatcher            alias for "debug.event_dispatcher"

Ага, значит диспетчер событий это реализация TraceableEventDispatcher.

Мы знаем, что для оптимизации, Symfony не работает с классами напрямую, и поэтому кэширует многие классы в кэш-директории. Диспетчер событий тоже кэшируется, в файле app/cache/dev/appDevDebugProjectContainer.php, в методе \appDevDebugProjectContainer::getDebug_EventDispatcherService:

$this->services['debug.event_dispatcher'] = new \Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher(
    new \Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher($this),// диспетчер событий
    $this->get('debug.stopwatch'),//
    $this->get('monolog.logger.event', ContainerInterface::NULL_ON_INVALID_REFERENCE)// логгер
);

Как видите TraceableEventDispatcher по сути не является диспетчером событий, а является оберткой над диспетчером ContainerAwareEventDispatcher. Зачем так сделано? Официальный ответ - чтобы узнать какие слушатели были вызваны при наступлении событий (так сказать, для дебага).

ContainerAwareEventDispatcher является потомком класса EventDispatcher.

Вводная часть

Компонент EventDispatcher пытается нас запутать используя термины Listener и Subscriber, но по факту это является одной сущностью - слушателем.

И прежде чем продолжить, хочу определить понятие:

ID сервиса - то имя, которое Вы объявляете в app/config/config.yml в секции services.

В ContainerAwareEventDispatcher есть 2 способа добавления слушателей:

1. Способ

addListenerService($eventName, $callback, $priority = 0) где:

$eventName - имя события, на которое подписываем
$callback - кого подписать - массив вида: [
    0 => ID сервиса,
    1 => метод, который должен быть вызван
]
$priority - приоритет вызова.

Пример использования:

$eventDispatcher = new Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher($container);
$eventDispatcher->addListenerService(
    'kernel.request',
    array(0 => 'assetic.request_listener', 1 => 'onKernelRequest'),
    0
);

таким образом, при срабатывании события kernel.request произойдет вызов:

$listener = new \Symfony\Bundle\AsseticBundle\EventListener\RequestListener();
$listener->onKernelRequest($event);

2. Способ

addSubscriberService($serviceId, $class) где:

$serviceId - кого подписать (ID сервиса)
$class - класс, в котором eventDispatcher возьмет настройки подписки. У данного класса должен существует статичный метод getSubscribedEvents(), данный метод должен отдать массив вида:
[
    $eventName - имя события, на которое подписываем выше указанный сервис => [
        0 => имя метода, который должен быть вызван для срабатывании события $eventName
        1 => приоритет вызова
    ],
    $eventName2 => ...
]

Пример использования:

$eventDispatcher = new Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher($container);
$eventDispatcher->addSubscriberService(
    'debug.debug_handlers_listener',
    'Symfony\\Component\\HttpKernel\\EventListener\\DebugHandlersListener'
);

таким образом Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::getSubscribedEvents() знает на какие события нужно подписать сервис debug.debug_handlers_listener.

Запутано - да, но что поделать, как мы видим Symfony-программисты не ищут легких путей

А еще в TraceableEventDispatcher реализованы методы

  • preProcess - оборачивает каждого слушателя в обертку \Symfony\Component\EventDispatcher\Debug\WrappedListener
  • postProcess - удаляет каждому слушателю обертку \Symfony\Component\EventDispatcher\Debug\WrappedListener

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

Всем удачки.

Оцени публикацию:
  • 0,0
Оценили человек: 0

Похожие статьи:

Справочники и учебники:


Предложения и пожелания:
Ваше имя:
Ваш E-mail:
Сколько будет Οдин + Τри
Главная
X

Новые заметки:

Про что мы забываем когда делаем оценку задачи по времени

Список вопросов для собеседования разработчика по телефону

Symfony2 авторизация без Doctrine2 для чайника

Phpstorm7 LiveEdit

Жесткий хабр или не хабр, тогда кто?

Яндекс.Деньги мошенничество

Как узнать какие страницы в поиске яндекса или это секрет

Последние комменты:

Yapro CMS:

Здравствуйте, Гость | Войти | Регистрация | Карта сайта | RSS ленты | Ошибка в тексте? Выделите её мышкой и нажмите: Ctrl + Enter

youtube.com/watch?v=7hFivbgIEqk

При полном или частичном использовании материалов данного сайта, ссылка на сайт "yapro.ru" обязательна как на источник информации.
Автоматический импорт материалов и информации с сайта запрещен.
Copyrights © 2007 - 2018 YaPro.Ru

Главная » Веб-мастеру » PHP »