服务构造函数中的 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\MyCustomListener
在 invokables
或 factories
下注册您的侦听器,以便能够像这样将其附加到此处。
回答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);
}
}
我在 Apigility 中附加 OnDispatch
事件时遇到问题。我想在我的抽象服务 Class 的构造函数中从自定义 header 中获得价值。当我简单地将它添加到 Module.php
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\MyCustomListener
在 invokables
或 factories
下注册您的侦听器,以便能够像这样将其附加到此处。
回答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);
}
}