ZF2 - 在一个模块中创建onbootstrap事件取代所有其他模块

时间:2014-09-18 14:43:04

标签: php zend-framework2

我有一个名为" Browsercheck"的ZF2模块,当与其他模块一起使用时,检查用户的浏览器并显示"不支持的浏览器"页面如果不支持浏览器。我遇到的问题是,以下代码是" Browsercheck"的onBootstrap。当其他模块遇到异常或404错误时,不会采取第一优先选择。否则,它会起作用。

如何确保此代码针对每个事件执行并取代任何其他事件?理想情况下,在ZF1中,我在index.php中使用这样的代码..但不确定它应该如何在ZF2中。基本上,如果浏览器不受支持,那么它是404还是异常并不重要。它应该继续并呈现不受支持的浏览器页面。

public function onBootstrap(MvcEvent $e)
{   
    $sharedEvents = $e->getApplication()->getEventManager()->getSharedManager();
    $sharedEvents->attach('Zend\Mvc\Controller\AbstractController','dispatch',
    function($event)
    {
        $browser = new \BrowserCheck\Service\BrowserCheck();
        if (!$browser->isCompatible())
        {
            $viewModel = new \Zend\View\Model\ViewModel();
            $viewModel->setTerminal(true);

            $request = $event->getRequest();
            $response = $event->getResponse();


            $viewModel->setTemplate('browser-check/index/index.phtml');
            //Replace the entire view
            $event->setViewModel($viewModel);
            $event->stopPropagation();
            $response->setStatusCode(200);
            return $viewModel;
        }
    });
}

更新

$browserEventListener = function($event)
    {
        $browser = new \BrowserCheck\Service\BrowserCheck();
        if (!$browser->isCompatible())
        {
            $viewModel = new \Zend\View\Model\ViewModel();
            $viewModel->setTerminal(true);

            $request = $event->getRequest();
            $response = $event->getResponse();

            $viewModel->setTemplate('browser-check/index/index.phtml');

            //Replace the entire view
            $event->setViewModel($viewModel);
            $event->stopPropagation();
            $response->setStatusCode(200);
            return $viewModel;
        }
    };
$sharedEvents = $e->getApplication()->getEventManager()->getSharedManager();
$sharedEvents->attach('Zend\Mvc\Controller\AbstractController',
  array('dispatch','dispatch.error'), $browserEventListener, 100);

1 个答案:

答案 0 :(得分:0)

这里的问题是您在dispatch事件之后注册事件监听器,该事件发生在bootstrap之后和route事件之后。如果在route事件处触发的事件侦听器无法识别路由,则会收到404错误页面,并且在调用任何其他dispatch事件侦听器之前,应用程序生命周期将终止。

为了在应用任何路由之前调用您的事件侦听器,您现在有两个选项:

  • bootstrap事件中注册您的事件监听器,使用较低的prio(例如,低于10000
  • 或者在route侦听器上注册优先级更高,10应该足够了

根据ZF2 doc page,调用onBoostrap()模块方法优先级为10000onRoute() \Zend\Mvc\ModuleRouteListener方法优先调用\Zend\Mvc\RouteListener1方法public function onBootstrap(MvcEvent $e) { /* ... all the default stuff here ... */ $this->registerBrowserCheckEvent($e); } private function registerBrowserCheckEvent(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $browserEventListener = function ($event) { $browser = new \BrowserCheck\Service\BrowserCheck(); if (!$browser->isCompatible()) { $viewModel = new \Zend\View\Model\ViewModel(); $viewModel->setTerminal(true); $request = $event->getRequest(); $response = $event->getResponse(); $viewModel->setTemplate('browser-check/index/index.phtml'); //Replace the entire view $event->setViewModel($viewModel); $event->stopPropagation(); $response->setStatusCode(200); return $viewModel; } }; $eventManager->attach(MvcEvent::EVENT_BOOTSTRAP, $browserEventListener, 100); } (优先级越高的数字)。

编辑:

你应该这样做:

{{1}}

另请注意,ZF2使用PSR-2(至少),您的代码也应遵循此约定(请注意您的代码与我的代码之间的细微差别)。