В настоящее время у меня есть приложение ZF2, настроенное с одним модулем «приложение». Я запускаю приложение и прикрепляю событие таким образом:
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach( $eventManager);
$this->initTracking( $e);
}
/**
* Initialises user tracking check
* @param MvcEvent $e
*/
public function initTracking( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach( 'dispatch', function( $e){
$objTracking = new \Application\Event\Tracking( $e);
}, 200);
}
}
Теперь мне нужно создать новый модуль «api», который должен обрабатывать только URL-адреса, начиная с domain.com/api (я настраиваю маршрутизатор в файле конфигурации модуля «api» для обработки только таких URL-адресов).
Я загружаю модуль «api» так же, как и модуль «application», и прикрепляю выделенное событие:
namespace Api;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach( $eventManager);
$this->initLogging( $e);
}
/**
* Initialises loggging
* @param MvcEvent $e
*/
public function initLogging( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach( 'dispatch', function( $e){
$objLogger = new \Application\Event\Logging( $e);
}, 200);
}
}
Что происходит, когда я вызываю domain.com/application — оба модуля инициализируются и запускаются события из обоих модулей. Мне нужно, чтобы события запускались в зависимости от приложения, которое отправляет действие.
Как я могу этого достичь?
В настоящее время вы подключаете прослушиватели событий к менеджеру событий приложения. Это единственный экземпляр менеджера событий, который будет запускать все события MVC.
Как это так же экземпляр это не будет иметь никакого значения где вы прикрепляете слушателей; все они будут запущены независимо.
Вам нужно будет специально проверить в каждом слушателе, является ли соответствующий маршрут тем, который слушатель должен выполнить. Если это не так, выходите рано.
Например:
public function onBootstrap(MvcEvent $event)
{
$eventManager = $event->getApplication()->getEventManager();
// There is no need to pass in the event
// to a seperate function as we can just attach 'initLogging' here
// as the event listener
$eventManager->attach('dispatch', array($this, 'initLogging'), 200);
}
// initLogging listener
public function initLogging(MvcEvent $event)
{
//... check the route is one you want
// this is quite basic to you might need to edit to
// suit your specific needs
$routeName = $event->getRouteMatch()->getMatchedRouteName();
if (false === strpos($routeName, 'api')) {
// we are not an api route so exit early
return;
}
$objLogger = new \Application\Event\Logging($event);
}
Таким образом, слушатель все равно будет активирован, однако он ничего не будет «делать».
Тем не менее, вы можете пойти дальше и предотвратить этот ненужный вызов, указав целевой менеджер событий, который вас интересует; чтобы сделать это, мы можем использовать SharedEventManager
,
При подключении слушателя к SharedEventManager
вам нужно предоставить «идентификатор» целевого менеджера событий — я предполагаю, что вы нацелены на «контроллер API».
Таким образом, вышеизложенное будет изменено на
public function onBootstrap(MvcEvent $event)
{
$application = $event->getApplication();
$sharedEventManager = $application->getEventManager()
->getSharedManager();
// The shared event manager takes one additional argument,
// 'Api\Controller\Index' is our target identifier
$eventManager->attach('Api\Controller\Index', 'dispatch', array($this, 'initLogging'), 200);
}
// initLogging listener
public function initLogging(MvcEvent $event)
{
// ... same bits we had before
}
метод onDispatch будет запущен только в одном модуле
namespace Application;
use Zend\Http\PhpEnvironment\Request;
use Zend\Http\PhpEnvironment\Response;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\ModuleManagerInterface;
use Zend\Mvc\MvcEvent;
/**
* @method Request getRequest()
* @method Response getResponse()
*/
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return array_merge(
require __DIR__ . '/../config/module.config.php',
require __DIR__ . '/../config/router.config.php'
);
}
public function init(ModuleManagerInterface $manager)
{
$eventManager = $manager->getEventManager();
// Register the event listener method.
$sharedEventManager = $eventManager->getSharedManager();
$sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH,
[$this, 'onDispatch'], 100);
}
public function onDispatch(MvcEvent $e)
{
var_dump(__METHOD__);
}