服务构造函数中的 OnDispatch 事件

OnDispatch event in Service Constructor

我在 Apigility 中附加 OnDispatch 事件时遇到问题。我想在我的抽象服务 Class 的构造函数中从自定义 header 中获得价值。当我简单地将它添加到 Module.php

中的 bootstrap 时,它 有效
public function onBootstrap(MvcEvent $e)
{
    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
    $eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
}

public function onDispatch(\Zend\Mvc\MvcEvent $e){
    $e->getRequest()->getHeaders()->get('User-Token')->getFieldValue();
}

但是我不知道如何将这个值传递给 ServiceAbstract Constructor。

我也尝试过实现 EventManagerAwareInterface 并使用 attachDefaultListeners() 方法附加事件,但这没有得到任何结果 - 附加函数没有被调用。附加到不在控制器中的事件的正确方法是什么?感谢您的帮助。

在我看来,您在这里有两个不同的目标。

1. 存储来自路线事件的 header 变量。

2. 获取一个变量进入class

的构造函数

回答1.

您可以创建一个侦听器 class 并将此 class 附加到您的 eventManager。这看起来像这样:

<?php

namespace My\Listener;

use Zend\EventManager\ListenerAggregateInterface;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Http\Headers;
use Zend\Http\Request as HttpRequest;

class MyCustomListener implements ListenerAggregateInterface
{
    /**
     * @var \Zend\Stdlib\CallbackHandler[]
     */
    protected $listeners = array();

    /**
     * @param EventManagerInterface $eventManager
     */
    public function attach(EventManagerInterface $eventManager)
    {
        // attach on route
        $this->listeners[] = $eventManager->attach(MvcEvent::EVENT_DISPATCH, array($this, 'onDispatch'));
    }

    /**
     * @param EventManagerInterface $eventManager
     */
    public function detach(EventManagerInterface $eventManager)
    {
        foreach ($this->listeners as $index => $listener) {
            if ($eventManager->detach($listener)) {
                unset($this->listeners[$index]);
            }
        }
    }

    /**
     * Do your thing on dispatch event with your headers
     *
     * @param MvcEvent $event
     */
    public function onDispatch(MvcEvent $event)
    {
        $request = $event->getRequest();
        if(!$request instanceof HttpRequest){
            // Nothing to do
            return;
        }

        $headers = $request->getHeaders();

        // You could for example get a service here and store your value
    }
}

您可以像这样在 Module.php 中附加此侦听器:

public function onBootstrap(MvcEvent $event)
{
    $event->getApplication();
    $application->getEventManager();
    $eventManager->attach($serviceManager->get('My\Listener\MyCustomListener'));
}

您必须在 ServiceManager 中使用密钥 My\Listener\MyCustomListenerinvokablesfactories 下注册您的侦听器,以便能够像这样将其附加到此处。

回答2:

要在您的构造函数中获取一个变量,您可以为您的 class 创建一个工厂,并从保存您需要的变量的服务中获取变量(可以直接从 1 的侦听器获取)。

<?php
namespace My\Factory;

use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use My\Folder\MyCustomClass;

class MyClassFactory implements FactoryInterface
{
    /**
     * @param  ServiceLocatorInterface $serviceLocator
     * @return Logger
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $controllerPluginManager = $serviceLocator;
        $service = $serviceManager->get(My\Service\MyStorageService);
        $dependency = $service->getDependency();
        return new MyCustomClass($dependency);
    }
}