1

堆栈:symfony2/doctrine2/php/mysql

多页表单由两个步骤组成。每个步骤都在控制器动作中实现。

在第 1 步中,显示表单。表单输入在同一操作中进行验证。如果表单有效,则应将用户重定向到第二步/操作。在第二步中,用户必须确认他的输入。确认后数据应存储在数据库中。

因此在第二步/动作中需要表单实体/表单数据。但是我不想在确认之前将其存储在数据库中。

我真的需要序列化所有对象吗?参加会议?有更好的方法吗?

有什么建议么?

4

2 回答 2

1

tried to use serialization, but entities are quite complex with "many" associations. thus serialization is too slow. even after detaching.

first solution (simplified):

store the POST variables to the session inside the first step/action.

    $postParams = $this->getRequest()->request;

    $session = $this->getRequest()->getSession();
    if (!$session) {
        $session = new Session();
    }
    $session->set($sessionKey, $postParams);

in the second step/action i used the form to repopulate my entity.

    $cancellation = $manager->initCancellationSomehow();

    $session = $this->getRequest()->getSession();
    if (!$session) {
        $session = new Session();
    }

    $parameterBag = $session->get($sessionKey);

    $cancellation = $this->getCancellation($customerId);

    $form = $this->createForm(
        new CancellationType(),
        $cancellation,
        array(
            'em' => $this->getDoctrine()->getManager())
    );

    $form->bind($parameterBag->get('form'));

    [..]

second solution:

well my first thought was to store cancellation in the db. therefore i added a state attribute (active/temp/..). unconfirmed cancellations get marked as temp. if the user confirms the state gets changed form temp to active. temp collections get deleted after on hour by a garbarge collector which runs at a low priority.

i like the second solution because the user has to confirm the final cancellation, which is already stored in the db. if the frontend does not work as expected the user will likely notice corrupted cancellations (e.g. wrong entries selected). if he confirms, only the state is changed. feels safe. in the first solution the user confirms what should be stored in the db, but isn't till now. feels unsecure.

于 2013-06-26T19:42:18.053 回答
1

首先,我建议在发布之前通过 JavaScript 验证输入,而不是在服务器上的控制器操作中验证输入。

如果您不想将数据序列化到会话中,您可以在第一个操作中收到数据时将其传递到下一页,然后将其发布到第二个操作,我想像这样:

firstAction() {
  $exampleData = $_POST['exampleData'];
  // Do whatever you need, then pass the data on to the next page
  return $this->render('SomeBundle:Views:secondPage.html.php',
                       array('exampleData' => $exampleData));

在第二页上,您只需要使用 JavaScript 访问 $exampleData 并最好将其放在表单内的某个隐藏输入字段中。

<!-- secondPage.html.php -->
<script type="text/javascript">
    var exampleData = <?php echo $exampleData ?>;
    $('#hiddenInput').val(exampleData);
</script>

然后,第二个控制器操作也将接收 $exampleData ,而无需在会话中对其进行序列化。

抱歉,如果有任何语法错误,有一段时间没有使用 symfony2 :)

于 2013-06-26T12:44:54.373 回答