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

Posted

技术标签:

【中文标题】Symfony 2:在 ContainerAwareCommand 中禁用 Doctrine 事件监听器【英文标题】:Symfony 2: Disable Doctrine event listener in ContainerAwareCommand 【发布时间】:2016-10-23 23:33:09 【问题描述】:

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

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

有没有办法为单个命令禁用特定的 EventLister?

【问题讨论】:

【参考方案1】:

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

$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


【讨论】:

【参考方案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;
        
    

【讨论】:

【参考方案3】:

将 Doctrine 侦听器中的逻辑包裹在 a 周围会更有意义:

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')

或者另一种方法,可能是:

    在 Doctrine 监听器中创建变量“启用” 在命令中注入 Doctrine 监听器 设置$this->myListener->enabled = false

【讨论】:

确实如此。但是,在我原来的情况下,我需要禁用自动更新时间戳等“一次性”/修复命令的侦听器。不完全是通常的情况 使用依赖注入不起作用,但通过其标识符获取服务确实有效(连同enabled 字段)

以上是关于Symfony 2:在 ContainerAwareCommand 中禁用 Doctrine 事件监听器的主要内容,如果未能解决你的问题,请参考以下文章

学习symfony 1.4会好用symfony 2.0吗?

Symfony 2 - 使用资产

10月进步一点点2.认识Symfony

如何在 symfony 2 中配置 SwiftMailer?

无法在 Symfony2 2.4 中安装 SonataUserBundle

Symfony 2:登录到特定文件