[英]ZF2 events for multiple modules
目前,我有一個配置有單個模塊“應用程序”的ZF2應用程序。 我以這種方式引導應用程序附加事件:
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach( $eventManager);
$this->initTracking( $e);
}
/**
* Initialises user tracking check
* @param MvcEvent $e
*/
public function initTracking( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach( 'dispatch', function( $e){
$objTracking = new \Application\Event\Tracking( $e);
}, 200);
}
}
現在,我需要創建一個新模塊“ api”,該模塊應僅處理以domain.com/api開頭的網址(我在“ api”模塊配置文件中將路由器配置為僅處理此類網址)。 我以與“應用程序”模塊相同的方式引導“ api”模塊,並附加一個專用事件:
namespace Api;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
class Module
{
public function onBootstrap( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$moduleRouteListener = new ModuleRouteListener();
$moduleRouteListener->attach( $eventManager);
$this->initLogging( $e);
}
/**
* Initialises loggging
* @param MvcEvent $e
*/
public function initLogging( MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach( 'dispatch', function( $e){
$objLogger = new \Application\Event\Logging( $e);
}, 200);
}
}
發生的是,當我調用domain.com/application時-兩個模塊都正在初始化,並且兩個模塊中的事件都被觸發。 我需要根據調度操作的應用程序來觸發事件。
我該如何實現?
您當前正在將事件偵聽器附加到應用程序事件管理器。 這是一個將觸發所有MVC事件的事件管理器實例。
因為是同一實例,所以在附加偵聽器的位置沒有任何區別; 它們都會被觸發。
您將需要在每個偵聽器中專門檢查匹配的路由是否是偵聽器應采取的措施。 如果不是,那就早退。
例如:
public function onBootstrap(MvcEvent $event)
{
$eventManager = $event->getApplication()->getEventManager();
// There is no need to pass in the event
// to a seperate function as we can just attach 'initLogging' here
// as the event listener
$eventManager->attach('dispatch', array($this, 'initLogging'), 200);
}
// initLogging listener
public function initLogging(MvcEvent $event)
{
//... check the route is one you want
// this is quite basic to you might need to edit to
// suit your specific needs
$routeName = $event->getRouteMatch()->getMatchedRouteName();
if (false === strpos($routeName, 'api')) {
// we are not an api route so exit early
return;
}
$objLogger = new \Application\Event\Logging($event);
}
因此,偵聽器仍將被觸發,但是不會“做任何事”。
但是,您可以通過專門針對您感興趣的所需事件管理器來進一步避免這種不必要的調用; 為此,我們可以使用SharedEventManager
。
將偵聽器附加到SharedEventManager
您需要提供目標事件管理器的“標識符”-我假設您的目標是“ API控制器”。
因此,以上內容將更改為
public function onBootstrap(MvcEvent $event)
{
$application = $event->getApplication();
$sharedEventManager = $application->getEventManager()
->getSharedManager();
// The shared event manager takes one additional argument,
// 'Api\Controller\Index' is our target identifier
$eventManager->attach('Api\Controller\Index', 'dispatch', array($this, 'initLogging'), 200);
}
// initLogging listener
public function initLogging(MvcEvent $event)
{
// ... same bits we had before
}
onDispatch方法將僅在一個模塊中運行
namespace Application;
use Zend\Http\PhpEnvironment\Request;
use Zend\Http\PhpEnvironment\Response;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\ModuleManager\ModuleManagerInterface;
use Zend\Mvc\MvcEvent;
/**
* @method Request getRequest()
* @method Response getResponse()
*/
class Module implements ConfigProviderInterface
{
public function getConfig()
{
return array_merge(
require __DIR__ . '/../config/module.config.php',
require __DIR__ . '/../config/router.config.php'
);
}
public function init(ModuleManagerInterface $manager)
{
$eventManager = $manager->getEventManager();
// Register the event listener method.
$sharedEventManager = $eventManager->getSharedManager();
$sharedEventManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH,
[$this, 'onDispatch'], 100);
}
public function onDispatch(MvcEvent $e)
{
var_dump(__METHOD__);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.