Php ZF2-使一个模块中的onbootstrap事件取代其他模块
我有一个名为Browsercheck的ZF2模块,当与其他模块一起使用时,会检查用户的浏览器,如果浏览器不受支持,则会显示不受支持的浏览器页面。我遇到的问题是,当其他模块遇到异常或404错误时,Browsercheck的引导上的以下代码不是首选代码。不然就行了 如何确保此代码针对每个事件执行并取代任何其他事件?理想情况下,在ZF1中,我在index.php中使用这样的代码。。但不确定它在ZF2中应该是怎样的。基本上,如果浏览器不受支持,那么无论它是404还是异常都不重要。它应该继续并呈现不受支持的浏览器页面Php ZF2-使一个模块中的onbootstrap事件取代其他模块,php,zend-framework2,Php,Zend Framework2,我有一个名为Browsercheck的ZF2模块,当与其他模块一起使用时,会检查用户的浏览器,如果浏览器不受支持,则会显示不受支持的浏览器页面。我遇到的问题是,当其他模块遇到异常或404错误时,Browsercheck的引导上的以下代码不是首选代码。不然就行了 如何确保此代码针对每个事件执行并取代任何其他事件?理想情况下,在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;
}
});
}
更新:
这里的问题是在调度事件上注册事件侦听器,该事件发生在引导和路由事件之后。如果在route event(路由事件)时触发的事件侦听器无法识别路由,则会收到404错误页面,并且在调用任何其他调度事件侦听器之前,应用程序生命周期将终止 为了在应用任何路由之前调用事件侦听器,您现在有两个选项: 在引导事件上以较低优先级(例如低于10000)注册事件侦听器 或者以更高的优先级在路由侦听器上注册它,10应该足够了 根据,调用onBoostrap模块方法的优先级为10000,调用\Zend\Mvc\ModuleRouteListener和\Zend\Mvc\RouteListener的onRoute方法的优先级为1,优先级越高 编辑: 你应该这样做:
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);
}
另外,请注意,ZF2至少使用PSR-2,您的代码应遵循此约定,同时请注意您的代码与我的代码之间的细微差异。此模块浏览器检查在您的应用程序配置中定义在哪个位置?你试过把它放在第一位吗?我确实放在了第一位。。还是一样的问题。好吧,那试试最后一个位置怎么样?对不起。我也这么做了。同样的问题。除了404和异常之外,该代码一直有效。不知何故,他们更喜欢这个,我不明白为什么。我也不明白,因为你把代码放进了你的onBoostrap方法中,应该在路由之前处理它。bootstrap事件作为所有事件中的第一个事件被触发,所有注册模块的bootstrap方法应该首先被调用,尽管我不清楚它们被调用的顺序。之后,触发路由事件,这就是404发生的地方。对PHP异常一无所知。您是否想过将这个特殊的浏览器处理移到index.php中?只是作为一个边缘案例解决方案来尝试?请参阅我的更新上面。当控制器操作发生异常和404时,上面更新的代码正在工作。但是,如果发生控制器未找到错误,则不会执行该命令。你能建议我如何修复它吗?@Jake你的目标是AbstractController事件管理器;如果找不到控制器,则AbstractController::dispatch将永远不会被触发。您应该将侦听器附加到应用程序服务管理器,而不是SharedEventManager。@alexp您能提供一个示例吗?
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);
}