2013-12-04 2 views
0

Есть ли способ прослушать событие «отправки» пересылаемых контроллеров?ZF2: Слушайте отправку пересылаемых контроллеров

ControllerA.php

class ControllerA extends AbstractActionController 
{ 
    public function forwardAction() 
    {   
     $return = $this->forward()->dispatch('ControllerB')); 
     return $return; 
    } 
} 

ControllerB.php

class ControllerB extends AbstractActionController 
{ 
    public function indexAction() 
    {   
     return "forwarded"; 
    } 
} 

module.php

public function onBootstrap(\Zend\Mvc\MvcEvent $e) 
{ 
    $application = $e->getApplication(); 
    $eventManager = $application->getEventManager(); 

    $eventManager->attach('dispatch', array(
     $this, 
     'onDispatch' 
    )); 
} 

public function onDispatch(Event $event) 
{ 
    $controller = $event->getTarget(); 
    var_dump(get_class($controller)); 
} 

Выход

ControllerA 

Ожидаемое/Wanted

ControllerA 
ControllerB 

ответ

0

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

class MyAbstractActionController extends \Zend\Mvc\Controller\AbstractActionController { 


public static $dispatched; 


public function dispatch(RequestInterface $request, ResponseInterface $response = null) { 


    self::$dispatched[]=__CLASS__; 
    return parent::dispatch ($request, $response); 
} 
} 

class ControllerA extends MyAbstractActionController 
{ 
.... 
} 

class ControllerB extends MyAbstractActionController 
{ 
.... 
} 

После отправки, вы будете иметь массив в MyAbstractActionController :: посланного с именем всех классов, которые вы прошли через

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

+0

Вышеупомянутая проблема является серьезной плохой практикой, поскольку она опирается на статическое состояние (трудно проверить, легко компрометировать). Я привел подробное объяснение в другом ответе для более подходящих способов достижения этого. – weierophinney

0

событие отправки не срабатывает только один раз независимо от того, что. Плагин Forward не будет инициировать процесс отправки (и это не обязательно). Действие контроллера вызывается непосредственно через ->dispatch().

Я не уверен, чего именно вы пытаетесь достичь?

+0

Я хочу, чтобы поймать все диспетчерские события на каждом контроллере в моем модуле вместо прикрепления к каждому контроллеру по отдельности. Но похоже, что это невозможно при использовании форварда. – machete

+0

Зачем вам эти события? – akond

3

Существует два «правильных» способа подключения событий к контроллерам.

Во-первых, на заводе-изготовителе контроллера (у вас есть фабрика, правильно ?!), вы можете ввести экземпляр менеджера событий и любых прослушивателей вручную. (Это работает отчасти потому, что если вы сделаете это, инициализатор для EventManagerAwareInterface будет не-оп, как он обнаружит экземпляр EM уже присутствует.)

function ($controllers) { 
    $services = $controllers->getServiceLocator(); 

    $controller = new SomeController(); 
    $events = $services->get('EventManager'); 

    // Attaching here at 100; use the priority that makes sense for the listener 
    $events->attach('dispatch', $services->get('YourListener'), 100); 

    $controller->setEventManager($events); 
    return $controller; 
} 

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

Второй путь, и наиболее часто используется, чтобы использовать общий менеджер событий:

$sharedEvents = $events->getSharedManager(); 
$sharedEvents->attach(<identifier or array of identifiers>, 'dispatch', <listener>, <priority>); 

В этом случае, вы должны знать один или несколько «идентификаторы», которые представляют интерес для вас ,Для всех контроллеров, простирающихся один из ZF абстрактных контроллеров, следующие всегда присутствуют:

  • Zend\Stdlib\DispatchableInterface
  • Zend\Mvc\Controller\AbstractController

Теперь, в зависимости от типа контроллера, вы будете иметь дополнительные идентификаторы:

  • Контроллеры нормального действия также имеют Zend\Mvc\Controller\AbstractActionController.
  • Контроллеры REST имеют как AbstractActionController, так и Zend\Mvc\Controller\AbstractRestfulController.
  • Если вы используете Apigility, ресурсы REST также имеют ZF\Rest\RestController.

И, наконец, в дополнение к этим реализация по умолчанию также включает в себя FQCN контроллера в качестве идентификатора.

Что это значит, это обеспечивает вам детализацию привязанности. Если вы присоедините , используя FQCN в качестве идентификатора, слушатель будет только активирован , если этот конкретный контроллер вызывается! Если вы прикрепляете с помощью Zend\Mvc\Controller\AbstractActionController в качестве идентификатора, то прослушиватель будет запущен для любойAbstractActionController расширение! (А присоединение к Zend\Stdlib\DispatchableInterface означает что любых контроллера, который запускает событие отправки вызовет слушатель.)

Смежные вопросы