我有两个MVC模块,我尝试构建,一个(FBWsrv)带有JSON输出和不同的安全过程,以及正常web使用的主要MVC模块(FBWeb) 。我有所有的路线设置和主要工作。我遇到的问题是他们都有onBootstrap方法附加他们自己的事件侦听器,我想禁用侦听器,如果不是在正确的MVC模块。Zend Framework 2如何禁用多个MVC模块中的事件侦听器
我的路线看起来像这样:
模块FBWeb,在URL中的 “应用程序” 模块:
/app/controller/action/par1/val1
模块FBWsrv,这是在URL “wsrv”:
/wsrv/controller/action/par1/val1
正如我所说的,路线工作正常。我得到正确的控制器和行动。但问题是MVC事件监听器在两个模块上运行,甚至没有运行/ wsrv路由中的/ app。如果我在/ wsrv中,我想要做的是禁用/ app中的事件。
的模块的短版本是设置像这样:
FBWeb/Module.php:
class Module
{
public function onBootstrap(MvcEvent $e)
{
$this->sm = $application->getServiceManager();
$this->config = $e->getApplication()->getConfig();
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'addInstanceObjects'), 5000);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'securityDispatch'), 0);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 100);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'postDispatch'), -100);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), -5000);
}
FBWsrv/Module.php:
class Module
{
public function onBootstrap(MvcEvent $e)
{
$this->sm = $application->getServiceManager();
$this->config = $e->getApplication()->getConfig();
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach($eventManager);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'addWsrvInstanceObjects'), 5900);
//$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'securityWsrvDispatch'), 5800);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'preWsrvDispatch'), 5500);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'postWsrvDispatch'), 5400);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onWsrvDispatchError'), 5100);
}
我有securityWsrvDispatch禁用在FBWsrv中,当我测试一些东西时,但我希望它能在以后运行它自己的过程。现在,我只需要分离FBWeb事件,如果我在FBWsrv中运行,因为它们没有相关性。我知道它们都在运行,因为错误出现在相反的模块中。不知道如何做到这一点。
感谢您的帮助!
格雷格
编辑/ NOTES: 我也尝试安装听众之前添加一个简单的检查了NAMESPACE,但似乎这两个命名空间总是叫,这两个模块创建的听众,即使只有一个是需要的。你如何隔离它们? 我想这一点,它不工作:
if(__NAMESPACE__ == 'FBWeb'){
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'addInstanceObjects'), 5000);
...
一个var_dump(__NAMESPACE__);
始终显示印刷两个命名空间。
编辑 - 一个解决办法
首先,感谢安德鲁的一点,你引发了一些想法的,我要工作到项目中。但是,在我学习的过程中,我通过检查路线来解决我的主要问题,然后在不匹配的情况下简单地从函数返回,从而跳过模块中的任何其他设置。
我也巩固了我的调度事件,这减轻了我的困惑。真的没有任何需要额外的混乱。我知道这不是正确的方式,但它确实解决了我的问题。
(必须已安装航线名为 'fbweb' 和 'fbwsrv' 可以匹配你的模块,当然)
在FBWeb/Module.php:
// in FBWeb/Module.php
// (default web MVC module)
public function onBootstrap(MvcEvent $e)
{
// ... get eventmanager ...
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 1000);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), -5000);
}
public function preDispatch(MvcEvent $e)
{
$this->route = $e->getRouteMatch();
$this->matchedRouteName = explode('/', $this->route->getMatchedRouteName());
$this->route_root = $this->matchedRouteName[0];
// then just test if not in correct route
if($this->route_root != 'fbweb'){
// if NOT, bail here,
// and skip any other setup in this module dispatch
return;
}
// continue other normal stuff (ACL's, session stuff, etc)
// ...
}
在我的其他模块:FBWsrv /Module.php:
// in FBWsrv/Module.php
public function onBootstrap(MvcEvent $e)
{
// ... get eventmanager ...
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 5500);
$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), -4900);
}
public function preDispatch(MvcEvent $e)
{
$this->route = $e->getRouteMatch();
$this->matchedRouteName = explode('/', $this->route->getMatchedRouteName());
$this->route_root = $this->matchedRouteName[0];
// then just test if not in correct route
if($this->route_root != 'fbwsrv'){
// if NOT, bail here,
// and skip any other setup in this module dispatch
return;
}
// continue other normal stuff (ACL's, session stuff, etc)
// ...
}
这是个好主意,Andrew,谢谢!我确实遇到了Evan Coury的帖子[link](http://blog.evan.pro/module-specific-layouts-in-zend-framework-2),这看起来就是你所描述的。我认为这将为我想要的部分工作。但对于其中的一些,我不得不考虑它。阅读他的帖子之前,只是困惑了我。 :)但我认为你提到的只是引发了一个想法,所以我试着去测试...... :)但同时,我可能有一个解决方法,我从罗布艾伦发现:[链接](http:// akrabat.com/zend-framework-2/module-specific-bootstrapping-in-zf2/)我会在上面发表注释。谢谢! – gregthegeek 2013-04-23 23:08:50
好吧,我可以看到这是如何处理这个问题的正确方法。不过,我不确定我的ACL如何在封闭中工作。我需要重写一些我的preDispatch设置,因此它可以与getSharedManager()一起使用,所以我现有的代码还不能工作。尽管将其标记为解决方案。感谢您的时间来帮助我安德鲁! – gregthegeek 2013-04-24 00:00:08
当然你不需要使用闭包,用数组($ object,'method')或'class :: method'等替换闭包:) – Andrew 2013-04-24 07:46:10