ZF2:收听转发控制器的发送

时间:2013-12-04 13:59:02

标签: events zend-framework2 listener forward

有没有办法收听转发控制器的“调度”事件?

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

预期/通缉

ControllerA
ControllerB

3 个答案:

答案 0 :(得分: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>);

在这种情况下,您必须知道一个或多个&#34;标识符&#34;你感兴趣的。对于任何扩展其中一个ZF抽象控制器的控制器,始终存在以下内容:

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

现在,根据控制器类型,您将拥有其他标识符:

  • 普通操作控制器也有Zend\Mvc\Controller\AbstractActionController
  • REST控制器同时具有AbstractActionController和。{1}} Zend\Mvc\Controller\AbstractRestfulController
  • 如果您正在使用Apigility,则REST资源也有ZF\Rest\RestController

最后,除此之外,默认实现还包括 控制器的FQCN作为标识符。

这样做可以为您提供附件的粒度。如果你附上 使用FQCN作为标识符,只会触发侦听器 如果调用该特定控制器!如果你附上使用 Zend\Mvc\Controller\AbstractActionController作为标识符, 将为任何 AbstractActionController触发侦听器 延期! (附加到Zend\Stdlib\DispatchableInterface表示 触发调度事件的任何控制器将触发 听众。)

答案 1 :(得分:0)

无论如何,只会触发一次调度事件。 Forward插件不会重新启动调度过程(并且不需要)。控制器的操作直接通过->dispatch ()调用。

我不确定你到底想要达到什么目的?

答案 2 :(得分: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 :: dispatched中拥有一个数组,其中包含您所经历的所有类的名称

请注意我没有尝试过这段代码,可以找到一些错误,而且你需要模块中的代码在调度后检索列表