事件侦听器更新其他实体和无限循环



在我的应用程序中,我有"用户"。 一个用户可以拥有多个"帐户">

我的"帐户"实体上有一个侦听器。 它是在"service.yml"文件上声明的,如下所示:

account_listener:
class: AppBundleEventListenerAccountListener
arguments:
- '@service_container'
tags:
- {name: doctrine.event_listener, event: preUpdate}

在我的服务中,方法预更新:

public function preUpdate(PreUpdateEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if (!$entity instanceof Account) {
return;
}
$this->container->get('notification_manager')->sendNotification();
}

sendNotification 方法调用尝试创建实体"通知"的函数

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

有了这个,它就可以工作了。但我认为有更好的方法。

你可以帮我吗?

谢谢

如果你调用一个调用flush的服务,我认为removeEventListener方法是避免无限循环的不错方法。

如果你真的不想叫removeEventListener,你必须改变你的模式,不要在教义事件中叫同花顺。

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

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

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

此外,在服务中注入容器是一种不好的做法,您应该只注入所需的服务和/或参数。

希望它会有所帮助

php 卡住的原因如下。

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

现在,当您的发送通知操作将被调用并且您保存Notification()时,事件侦听器将被调用,并且从事件侦听器再次调用sendNotification方法等等.....这将创建递归循环,这就是ypur php卡住的原因。

希望对您有所帮助。

最新更新