Symfony 2:在ContainerAwareCommand中禁用Doctrine事件侦听器

时间:2016-06-22 07:15:59

标签: php symfony doctrine-orm command event-listener

我正在使用在配置文件中注册的几个Doctrine侦听器进行一些自动更新(created_on,updated_on timestamps等)。 目前,我已经实现了其他功能,需要在数据库中存储准备好的值,以便于搜索。

我正在考虑更新Symfony命令,它将准备这些值而不是SQL更新脚本(实际上,任何类型的更改或更新的方式都是值,只需运行此单个命令)。但是,这也会触发前面提到的EventListeners。

有没有办法如何为单个Command禁用特定的EventLister?

3 个答案:

答案 0 :(得分:7)

这样的事情应该可以解决问题:

$searchedListener = null;
$em = $this->getDoctrine()->getManager();
foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
    foreach ($listeners as $key => $listener) {
        if ($listener instanceof ListenerClassYouLookFor) {
            $searchedListener = $listener;
            break 2;
        }
    }
}
if ($searchedListener) {
    $evm = $em->getEventManager();
    $evm->removeEventListener(array('onFlush'), $searchedListener);
}
else { //listener not found

}

答案 1 :(得分:2)

services.yaml中,我的监听器是这样定义的:

services: 
    App\EventListener\DoctrinePostUpdateListener:
        tags:
            - { name: doctrine.event_listener, event: postUpdate }

我在侦听器类中添加了条件停止执行的私有变量$enabled

class DoctrinePostUpdateListener
{
    private $enabled = true;    

    public function postUpdate(LifecycleEventArgs $args) 
    {
        if ($this->enabled === false) { //stop execution
            return;
        }

        .. your code to execute ..

        return;
    }

    public function setEnabled(bool $enabled)
    {
        $this->enabled = $enabled;
    }

}

然后在我不想执行此侦听器的service/controller代码中,我仅将此$enable变量设置为false:

    $listeners = $this->em->getEventManager()->getListeners('postUpdate');
    foreach ($listeners as $key => $listener) {
        if ($listener instanceof DoctrinePostUpdateListener) {
            $listener->setEnabled(false);
            break;
        }
    }

答案 2 :(得分:0)

将Doctrine侦听器中的逻辑包装在:

中更有意义

if ($this->enabled) {

所以每个人都可以理解逻辑是否可以被禁用。

您可以使用参数来启用或不启用代码(请参阅http://symfony.com/doc/current/service_container/parameters.html)。

my_doctrine_listener_enabled: true

您在命令中将其设置为false:

$container->setParameter('my_doctrine_listener_enabled', false);

由于参数在运行时被修改,我建议您不要通过DIC而是通过

使用它
$container->getParameter('my_doctrine_listener_enabled')

或者另一种方法可能是:

  1. 创建变量"已启用"在Doctrine听众中
  2. 在命令中注入Doctrine侦听器
  3. 设置$this->myListener->enabled = false