繁体   English   中英

多个模块的ZF2事件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM