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

Wol*_*fer 7 php command event-listener symfony doctrine-orm

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

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

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

小智 10

像这样的东西应该做的伎俩:

$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

}
Run Code Online (Sandbox Code Playgroud)


小智 5

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

services: 
    App\EventListener\DoctrinePostUpdateListener:
        tags:
            - { name: doctrine.event_listener, event: postUpdate }
Run Code Online (Sandbox Code Playgroud)

在我的监听器类中,我添加了$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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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

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