我有兩個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