在zend框架2中的控制器操作之后调用的侦听器类中的__invoke

时间:2014-11-08 10:52:28

标签: php zend-framework zend-framework2 zend-framework-mvc

我创建了一个事件监听器,并将其附加到controller中的特定onBootstrap。问题是在调用控制器操作后调用__invoke函数。除此之外的一切都运转良好。

工厂

public function getServiceConfig() {
        return array(
            'factories' => array(
                'Api\Adapter\HeaderAuthentication' => 'Api\Factory\AuthenticationAdapterFactory',
                'Api\Listener\AuthenticationListener' => 'Api\Factory\AuthenticationListenerFactory',
            ),
        );
    }

自举

public function onBootstrap(MvcEvent $e) {
        $app = $e->getApplication();
        $sm = $app->getServiceManager();
        $em = $app->getEventManager();

        $moduleRouteListener = new ModuleRouteListener();
        $moduleRouteListener->attach($em);

        $listener = $sm->get('Api\Listener\AuthenticationListener');
        $em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener);
    }

我创建了Api\Controller类型的基本控制器Zend\Mvc\Controller\AbstractRestfulController,然后我会将此控制器继承给所有其他控制器。

ListenerFactory

class AuthenticationListenerFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sl)
    {
        $name    = 'Api\Adapter\HeaderAuthentication';
        $adapter = $sl->get($name);

        $listener = new AuthenticationListener($adapter);
        return $listener;
    }
}

AuthenticationListener

class AuthenticationListener {

    protected $adapter;

    public function __construct(HeaderAuthentication $adapter) {
        $this->adapter = $adapter;
        die('died in listener'); // this executes before controller execution.
    }

    public function __invoke(MvcEvent $event) { // this executes after controller action execution
        $result = $this->adapter->authenticate();
        die('died in listener'); 
        if(!$result->isValid()){
            $response = $event->getResponse();
            $response->setStatusCode(400);

            $responseMessages = '';
            foreach($result->getMessages() as $message) {
                $responseMessages .= $message . '. ';
            }
            $response->setContent($responseMessages);
            return $response;
        }

        $event->setParam('user', $result->getIdentity());

    }

}

1 个答案:

答案 0 :(得分:1)

好的,我发现的很有趣。在ZF2 postDispatchpreDispatch中,可以通过确定事件的优先级来实现。只需为您的活动添加优先级,例如

$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, 100);

默认情况下,事件的优先级为1。优先级大于1 的所有事件在操作前调用并充当preDispatch。如果小于或等于1的数字会使其成为postDispatch

$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener); // postDispatch
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, 100); // preDispatch
$em->getSharedManager()->attach('Api\Controller', 'dispatch', $listener, -100); // postDispatch