我有一个名为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) ;
答案 0 :(得分:2)
SharedEventManager::attach()
的第一个参数是要定位的事件管理器的标识。此标识是为任何具有事件功能的类(实现Zend\EventManager\EventManagerAwareInterface
)动态分配的,或者通过$eventManager->setIdentity()
设置其身份。
问题涉及\Zend\Mvc\Controller\AbstractActionController
;这本身就是赋予任何扩展\Zend\Mvc\AbstractActionController
(以及其他)的控制器的身份,允许只有一个id attach()
来定位所有控制器。
要仅定位一个控制器(完全有效,有许多用例),您可以通过两种方式实现:
SharedEventManager
,在控制器类外部(正如您所做的那样)通过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\
供应商名称空间