【问题标题】:Symfony2 Doctrine - Flushing in kernel.response listener flushs bad dataSymfony2 Doctrine - 在 kernel.response 监听器中刷新会刷新坏数据
【发布时间】:2015-03-16 21:50:42
【问题描述】:

为了给我的 Symfony2 应用做一些日志记录,我创建了一个记录任何连接的服务,这里是 kernel.response 上调用的方法:

public function log(FilterResponseEvent $event)
{
    $log = new Log();
    $request = $event->getRequest();
    $response = $event->getResponse();
    //fill the Log entity with stuff from request & response data

    $manager = $this->container->get('doctrine.orm.entity_manager');
    $manager->persist($log);
    $manager->flush();
}

这一切看起来都很好,但是当我执行这样的测试时(使用空数据修补以触发失败):

$this->client->request(
    'PATCH', 
    '/users/testificate', 
    array(
        'firstName' => '',
    )
);

调用此操作:

protected function processForm($item, $method = 'PATCH')
{
    $form = $this->createForm(new $this->form(), $item, array('method' => $method));
    $form->handleRequest($this->getRequest());

    if ($form->isValid()) {
        $response = new Response();

        // Set the `Location` header only when creating new resources
        if ($method == 'POST') {
            $response->setStatusCode(201);
            $response->headers->set('Location',
                $this->generateUrl(
                    'get_' . strtolower($class), array('slug' => $item->getId()),
                    true // absolute
                )
            );
        }
        else {
            $response->setStatusCode(204);
        }
        $this->em->flush();

        return $response;
    }
    $this->em->detach($item);
    return RestView::create($form, 400);
}

虽然测试失败了,但实体已经打了补丁,当然不能。 经过一番搜索,我了解到:

  • 参数进入表单验证器
  • 验证失败,因此返回 400 http 代码而不刷新实体
  • 但是在验证过程中,实体会因无效数据而受到影响
  • 在 kernel.response 上调用服务时,$manager->flush();刷新所有数据...包括 PATCH 测试提供的不良数据。

到目前为止我已经尝试过: 1) 做一个 $manager->clear(); $manager->persist() 之前; ...不会改变任何东西 2) 做一个 $manager->detach($item);如果表单验证失败......不会改变任何东西

谢谢!

【问题讨论】:

    标签: symfony doctrine listener flush


    【解决方案1】:

    我最近在从 Doctrine 2.3.4 升级到最新的 2.4 分支时偶然发现了 kernel.response 中的刷新问题。尝试从kernel.terminate 刷新日志实体。在kernel.response 中保留对响应的任何修改。

    【讨论】:

    • 谢谢!它奏效了:) 我有一个临时解决方案:使用$connection = $manager->getConnection(); 在数据库中手动插入数据但是你的方法更好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    相关资源
    最近更新 更多