EventListener更新其他实体和无限循环

时间:2017-02-28 16:05:19

标签: symfony

在我的申请中,我有#34;用户"。 一个用户可以拥有多个"帐户"

我在"帐户上有一个听众"实体。 它在" service.yml"上声明。像这样的文件:

account_listener:
    class: AppBundle\EventListener\AccountListener
    arguments:
        - '@service_container'
    tags:
        - {name: doctrine.event_listener, event: preUpdate}

在我的服务中,方法是preUpdate:

public function preUpdate(PreUpdateEventArgs $eventArgs)
{
    $entity = $eventArgs->getEntity();
    if (!$entity instanceof Account) {
        return;
    }

    $this->container->get('notification_manager')->sendNotification();
}

sendNotification方法调用一个尝试创建实体的函数" notification"

public function sendNotification()
{
    $notification = new Notification();
    $data = array(
                    'label' => 'Hello'
                )
    $form_notif = $this->formFactory->create(NotificationType::class, $notification, ['method' => 'POST']);
    $form_notif->submit($data,($method === 'POST'));
    if ($form_notif->isValid())
    {
        $this->em->persist($notification);
        $this->em->flush();
    } else {
        return $form_notif;
    }
    return $notification;

}

问题: 没有创建通知,并且php陷入无限循环。

为了防止这种情况,我在sendNotification方法的开头添加了这个:

$eventManager = $this->em->getEventManager();
$eventManager->removeEventListener(['preUpdate'],$this->container->get('account_listener'));

有了它,它有效。但我认为还有更好的方法。

你能帮助我吗?

由于

2 个答案:

答案 0 :(得分:0)

如果你拨打一个呼叫flush的服务,我认为removeEventListener方法避免无限循环并不是一种坏方法。

如果你真的不想打电话给removeEventListener,你必须改变你的模式而不是在学说事件中调用同花。

一种替代方法是使用第三个服务和要刷新的对象集合(在您的情况下,NotificationStack类具有单个集合和少量getter / setter)。

您的sendNotification方法会在此集合中添加元素(不会刷新它们)。

然后,您可以在kernel.response事件(和/或console.terminate,如果需要)上清除所有该集合。

另外,在服务中注入容器是一个不好的实践,你应该只注入所需的服务和/或参数。

希望它会有所帮助

答案 1 :(得分:0)

php卡住的原因如下。

在你的代码中,你调用preUpdate(),当你插入或更新实体时调用它。

现在当你的sendNotification操作被调用并且你保存Notification()时,eventlistener将被调用,并且从eventlistener它再次调用sendNotification方法等等.....这将创建递归循环,这就是为什么ypur php卡住了。

希望它会对你有所帮助。