【问题标题】:Dispatch controller zf2 event manager调度控制器 zf2 事件管理器
【发布时间】:2014-06-29 20:36:06
【问题描述】:

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

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

但确实如此:

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

【问题讨论】:

  • 错误是什么?你确定 MyController 是可见的吗?也许你应该放一些像 Controller\MyController (with namespace)

标签: php zend-framework2


【解决方案1】:

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

问题指的是\Zend\Mvc\Controller\AbstractActionController;这本身就是为任何扩展 \Zend\Mvc\AbstractActionController(以及其他)的控制器提供的标识,允许只有一个 id 到 attach() 以针对所有控制器。

要仅针对一个控制器(这是完全有效的,有许多个用例),您可以通过两种方式做到这一点:

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

通过 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
    }

}

【讨论】:

    【解决方案2】:

    为什么要使用自己的基本控制器?这样做并没有真正的好处,除非您遇到罕见的极端情况。

    您的基本控制器类在 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\ vendor 命名空间

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      相关资源
      最近更新 更多