ZF2: How to attach module specific listener for di

2019-02-24 00:15发布

问题:

Is there a way I can attach an event listener for the event dispatch.error in Zend Framework 2, where that listener will only be attached to an EventManager related to the Module.php?

I have achieved this by attaching listener for dispatch to the global SharedManager and passing the current Module.php's namespace as first param. It works beautifully, but does NOT work, when I try the same for dispatch.error.

Here's an example in Module.php:

public function init(ModuleManager $moduleManager)
{
    $sharedManager  = $moduleManager->getEventManager()->getSharedManager();
    $sharedManager->attach(__NAMESPACE__, 'dispatch', function($e) {
        exit('IT WORKS');
    });
    $sharedManager->attach(__NAMESPACE__, 'dispatch.error', function($e) {
        exit('IT DOES NOT WORK');
    });
}

回答1:

The reason it is working for dispatch but not dispatch.error is that the dispatch event gets triggered from within in the controller (see Zend\Mvc\Controller\AbstractController::dispatch)

Because you extend this class with your own namespaced controller, it is possible to associate the event with that namespace.

However, the dispatch.error event may be triggered before a controller (and with it the context of your namespace) is ever loaded. This happens according to more than one condition in Zend\Mvc\DispatchListener.

In order to customize the way dispatch.error is handled, you will likely need to write a custom listener for that event, or even write your own DispatchListener (though I'd recommend against that). You can then perhaps look at the routeMatch to figure out what you'd like to do next. If you're using the ModuleRouteListener this could be pretty easy.