调度控制器zf2事件管理器

时间:2014-06-28 17:42:55

标签: php zend-framework2

我有一个名为MyController的基本控制器 我从MyController而不是AbstractActionController扩展我的Controller 这段代码有什么问题?
它没有用:

$sharedEventManager->attach('MyController', 'dispatch', function ($e) {
    $controller = $e->getTarget();
},100) ;

但这样做:

$sharedEventManager->attach('Zend\Mvc\Controller\AbstractActionController', 'dispatch', function ($e) {
    $controller = $e->getTarget();
},100) ;

2 个答案:

答案 0 :(得分:2)

SharedEventManager::attach()的第一个参数是要定位的事件管理器的标识。此标识是为任何具有事件功能的类(实现Zend\EventManager\EventManagerAwareInterface)动态分配的,或者通过$eventManager->setIdentity()设置其身份。

问题涉及\Zend\Mvc\Controller\AbstractActionController;这本身就是赋予任何扩展\Zend\Mvc\AbstractActionController(以及其他)的控制器的身份,允许只有一个id attach()来定位所有控制器。

要仅定位一个控制器(完全有效,有许多用例),您可以通过两种方式实现:

  1. 通过SharedEventManager,在控制器类外部(正如您所做的那样)
  2. 直接获取所述控制器的事件管理器并处理控制器类中的事件。
  3. 通过SharedEventManager

    使用完全限定的类名,因为它是作为标识添加到事件管理器

    $sharedEventManager->attach(
        'MyModule\Controller\FooController', 'dispatch', function($e){
        // do some work
    });
    

    在控制器内

    我修改了普通的attachDefaultListeners()方法(which is called automatically),您可以在此处直接附加事件。

    namespace MyModule\Controller;
    
    use Zend\Mvc\Controller\AbstractActionController;
    use Zend\EventManager\EventInterface;
    
    class FooController extends AbstractActionController
    { 
        protected function attachDefaultListeners()
        {
          // make sure you attach the defaults!
          parent::attachDefaultListeners();
    
          // Now add your own listeners
          $this->getEventManager()->attach('dispatch', array($this, 'doSomeWork'));
        }
    
        public function doSomeWork(EventInterface $event) {
          // do some work
        }
    
    }
    

答案 1 :(得分:1)

为什么使用自己的基本控制器?除非你有罕见的边缘情况,否则没有真正的好处。

您的基本控制器类在AbstractController中缺少此部分:

/**
 * Set the event manager instance used by this context
 *
 * @param EventManagerInterface $events
 * @return AbstractController
 */
public function setEventManager(EventManagerInterface $events)
{
    $events->setIdentifiers(array(
        'Zend\Stdlib\DispatchableInterface',
        __CLASS__,
        get_class($this),
        $this->eventIdentifier,
        substr(get_class($this), 0, strpos(get_class($this), '\\'))
    ));
    $this->events = $events;
    $this->attachDefaultListeners();

    return $this;
}

在那里看setIdentifiers来电?这就是为什么第二个例子有效的原因。

此外,我怀疑您可能实际上并未在控制器的dispatch()方法中触发调度事件

旁注:您不应该创建没有顶级命名空间的类。例如,我的所有课程都使用Xrks\供应商名称空间