symfony - EventListener 更新其他实体并死循环

标签 symfony

在我的应用程序中,我有“用户”。 一个用户可以有多个“账户”

我的“帐户”实体上有一个监听器。 它在“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 方法调用一个尝试创建实体“通知”的函数

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,你必须改变你的模式,而不是在 doctrine 事件中调用 flush。

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

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

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

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

希望对你有帮助

关于symfony - EventListener 更新其他实体并死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42513530/

相关文章:

forms - 使用表单事件时的 Symfony 表单字段顺序

php - Symfony,重定向到(或呈现)带有 404 状态返回码的 404 自定义错误页面

php - 将 Docker 容器部署到 AWS 时运行数据库迁移命令

php - Symfony2 : Getting Route in Page Load Event Listener

Symfony2 Doctrine : redefine annotation in a inheritance class from another bundle

Symfony3 : "The file/tmp/php4k3bf8 could not be accessed"

php - socket_create_listen 不适用于 Windows 中的所有接口(interface)

php - 删除级联中的实体在多对多关系中不起作用

php - 如何在symfony2中未经身份验证的页面中访问用户的角色

php - Symfony 在实体存储库类中获取 session 变量