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

Symfony 2: Disable Doctrine event listener in ContainerAwareCommand

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

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

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

像这样应该可以解决问题:

$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

}

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

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

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

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

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

对于我的听众 class 我添加了带有停止执行条件的私有变量 $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;
        }
    }