【问题标题】:Manipulate form data before persisting entity - Symfony 2.6在持久化实体之前操作表单数据 - Symfony 2.6
【发布时间】:2015-05-05 18:11:45
【问题描述】:

我有一个实体,它有一个名为 end_date 的字段,它是日期时间。在我的 symfony 表单中,我有一个未绑定的字段,您可以选择天数,例如 3 天、5 天、7 天。

我需要做的是操纵表单提供的天数(我不想进入数据库)并计算结束日期与所选天数的关系然后坚持 end_date。

我遇到的问题是如何在创建表单和将实体持久化到数据库之间进行数据操作。

这是我的表单功能:

public function saveNewListing($request, $controller){
        $listing = new Listing();
        $product = new Product();
        $listing->setProduct($product);
        $product->setUser($controller->getUser());
        $form = $controller->createForm(new SellType(), $auction)->handleRequest($request);

        if($form->isValid()) {
            $em = $controller->getDoctrine()->getManager();
            $em->persist($listing);
            $em->persist($product);
            $em->flush();
            return true;
        }
        return $form;
    }

在绑定表单数据和实体和检查表单是否有效之间,我应该在哪里操作数据?我还需要将新的 end_date 绑定到表单吗?还是只是将其绑定到实体?

谢谢

【问题讨论】:

    标签: php forms symfony entity symfony2-forms


    【解决方案1】:
       if($form->isValid()) {
                $em = $controller->getDoctrine()->getManager();
    
                $days = $request->get("form")["days"] 
                //* calc end date here $endDate as \DateTime */
                $listing->setEndDate($endDate);
    
                $em->persist($listing);
                $em->persist($product);
                $em->flush();
                return true;
     }
    

    【讨论】:

    • 感谢您的回复,请尝试一下
    【解决方案2】:

    虽然@Evgeniy 的回答在技术上是正确的,但我想稍微扩展一下。

    当您在 Symfony 中创建表单并调用 handleRequest 方法时,表单将被所有提交的字段填充。如果您想操作表单的数据,您有两种可能的选择:

    1. if($form->isValid()){} 代码块中的Controller 进行任何必要的修改。
    2. 创建表单事件并在填充数据之前/之后操作数据。 (Form events, Dynamic form modifications)

    这两个选项都同样正确。您选择什么取决于您的用例:

    1. 如果您打算在某个特定位置使用此FormType,您可以轻松地在Controller 中定义您的逻辑。
    2. 但是,如果您的FormType 将包含在其他位置并且需要保持与您应该编写表单事件侦听器/订阅者相同的功能。这将消除在Controller 中编写任何代码的需要,并为您提供最终的Entity 准备好保存到数据库中,而无需任何进一步的修改(因为它们已经在您的事件监听器中完成)创建)。

    【讨论】:

    • 感谢您的回复。我明白你的意思,虽然我编写的代码不需要在其他地方重用,但是感谢我之前不知道这些事件的提示,所以我肯定会在其他地方使用它们:)
    • tftd,我同意你关于 2 的可能方式。但从我在给定示例中看到的情况来看,这种情况似乎是“过度设计”。但是 AOP(实际上属于监听器)是一种非常酷的方法,可以更好地组织代码
    • @EvgeniyKuzmin 这取决于您的用例。表单事件通常用于更复杂的场景中,在这些场景中,您有大量的业务逻辑,并且您不能在需要再次使用相同的表单类型时复制/粘贴它。但如果你正在做一个非常简单的表格,那绝对是一个矫枉过正:)
    【解决方案3】:

    我建议你在 prePersist 的回调中这样做。这是一个很好的做法。更多关于这个http://symfony.com/doc/current/book/doctrine.html#lifecycle-callbacks

    【讨论】:

    • 这也是一个有效的选项,但应该注意的是,在表单字段未映射到实体属性的情况下,它不起作用。
    猜你喜欢
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 2016-04-13
    • 2014-02-10
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2014-08-25
    相关资源
    最近更新 更多