2013-04-23 68 views
2

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

} 

回答

4

你爲什麼不通過共享事件管理器連接使用方面的活動,有大量的文檔在那裏與共享活動經理幫助的。

/** 
* On bootstrap event 
* 
* @param \Zend\Mvc\MvcEvent $e 
*/ 
public function onBootstrap(MvcEvent $e) 
{ 
    // .. other stuff 

    /** 
    * Example attaching events with shared manager, using context 
    */ 
    $e->getApplication()->getEventManager()->getSharedManager() 
     ->attach('MyModule\Controller\AbstractActionController', 'dispatch', function($e) { 

     // do something to only be triggerd when dispatch is triggered 
     // on a controller extending your nice base controller in this module.. 

    }, 100); 
} 
+0

這是個好主意,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

+0

好吧,我可以看到這是如何處理這個問題的正確方法。不過,我不確定我的ACL如何在封閉中工作。我需要重寫一些我的preDispatch設置,因此它可以與getSharedManager()一起使用,所以我現有的代碼還不能工作。儘管將其標記爲解決方案。感謝您的時間來幫助我安德魯! – gregthegeek 2013-04-24 00:00:08

+0

當然你不需要使用閉包,用數組($ object,'method')或'class :: method'等替換閉包:) – Andrew 2013-04-24 07:46:10