Запуск событий с использованием EventDispatcher Symfony - PullRequest
0 голосов
/ 24 июня 2018

Я использую компонент EventDispatcher Symfony для запуска и обработки событий в моем приложении. Я создал глобальную вспомогательную функцию fire(Event $event) внутри файла Helpers.php, которую я автоматически загружаю с помощью composer.

Помощники.php

<?php

use App\Http\Helpers\ConfigManager;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;

//listeners array defined in another file.
$listeners = [
    [\App\Events\ExampleEvent::class => \App\Listeners\ExampleListener::class], 
    [\App\Events\JobEvent::class => \App\Listeners\JobEventListener::class]
];

if (!function_exists('fire')) {

    function fire(Event $event) {
        $dispatcher = new EventDispatcher();
        $listeners  = ConfigManager::getInstance()->getEventListeners();

        foreach ($listeners as $listener) {
            foreach ($listener as $ev => $handler) {
                $instance = new $handler;
                if (method_exists($instance, 'handle')) {
                    $dispatcher->addListener($ev, [$instance, 'handle']);
                }
            }
        }

        //events should be dispatched once
        //remove duplicate events name from events array.
        $events = array_unique(
                      array_map(function ($listener) {
                          return array_keys($listener)[0]; 
                      }, $listeners)
                  );

        foreach ($events as $ev) {
            if ($event instanceof $ev) {
                $dispatcher->dispatch($ev, $event);
            }
        }
    }

}

Я использую это так: fire(new ExampleEvent('payload'));

Эта функция доступна везде в моем приложении. Каждый раз, когда я вызываю ее, EventListeners в массиве $ listeners регистрируются, затемотправляется событие $.

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

Должен ли я зарегистрировать слушателей где-то еще, а затем просто запустить событие внутри функции, какие-нибудь идеи?

PS.Я не использую какие-либо рамки.

1 Ответ

0 голосов
/ 24 июня 2018

У меня не было способа загрузить приложение, поэтому все, что я сделал, это создал синглтон EventManager с двумя методами registerListeners() и fire(Event $event), затем я создал bootstrap.php (обходной путь), который я требуется один раз на модуль.

в моем bootstrap.php:

EventManager::getInstance()->registerListeners();

EventManager singleton:

<?php

namespace App\Http\Helpers;


use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;

class EventManager
{
    private $dispatcher = null;

    private $listeners = null;

    protected function __construct()
    {
        $this->dispatcher = new EventDispatcher();
        $this->listeners = ConfigManager::getInstance()->getEventListeners();
    }

    private function __clone() {} //nah, no clones.

    public static function getInstance()
    {
        static $instance = null;
        if ($instance === null) {
            $instance = new EventManager();
        }
        return $instance;
    }

    public function registerListeners()
    {
        foreach ($this->listeners as $listener) {
            foreach ($listener as $ev => $handler) {
                $instance = new $handler;
                if (method_exists($instance, 'handle')) {
                    $this->dispatcher->addListener($ev, [$instance, 'handle']);
                }
            }
        }
    }

    public function fire(Event $event)
    {
        //events should be dispatched once, remove duplicate event name from events array.
        $events = array_unique(array_map(function ($listener) { return array_keys($listener)[0]; }, $this->listeners));

        foreach ($events as $ev) {
            if ($event instanceof $ev) {
                $this->dispatcher->dispatch($ev, $event);
            }
        }
    }
}

вспомогательная функция fire(Event $event) выглядит следующим образом:

<?php

use App\Http\Helpers\EventManager;
use Symfony\Component\EventDispatcher\Event;

if (!function_exists('fire')) {

    function fire(Event $event) {
        EventManager::getInstance()->fire($event);
    }

}

Спасибо @Cerad за хедз-ап.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...