Symfony2:如何在将请求绑定到表单后获取表单验证错误

put*_*uan 109 symfony

这是我的saveAction代码(表单传递数据的地方)

public function saveAction()
{
    $user = OBUser();

    $form = $this->createForm(new OBUserType(), $user);

    if ($this->request->getMethod() == 'POST')
    {
        $form->bindRequest($this->request);
        if ($form->isValid())
            return $this->redirect($this->generateUrl('success_page'));
        else
            return $this->redirect($this->generateUrl('registration_form'));
    } else
        return new Response();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果$form->isValid()返回,我如何得到错误false

nef*_*o_x 117

您有两种可能的方法:

  • 不要在出错时重定向用户并{{ form_errors(form) }}在模板文件中显示
  • 访问错误数组为 $form->getErrors()

  • @mives您必须通过为每个字段显式设置选项,在表单类型中将`error_bubbling`设置为true. (59认同)
  • 我做了你建议的第二件事但是form-> getErrors()返回一个空白数组. (21认同)
  • 您还可以执行`$ form-> getErrors(true)`来包含子表单的错误 (12认同)
  • 如果您使用自定义验证器,Symfony不会返回$ form-> getErrors()中那些验证器生成的错误. (5认同)
  • 我也做了第一个(带有php模板<?php echo $ view ['form'] - > errors($ form)?>)但是它仍然是空的! (2认同)

Fli*_*lip 100

Symfony 2.3/2.4:

这个函数得到了所有的错误.表单上的"CSRF令牌无效.请尝试重新提交表单." 以及没有错误冒泡的表单子上的其他错误.

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = $this->getErrorMessages($child);
        }
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

要将所有错误作为字符串获取:

$string = var_export($this->getErrorMessages($form), true);
Run Code Online (Sandbox Code Playgroud)

Symfony 2.5/3.0:

$string = (string) $form->getErrors(true, false);
Run Code Online (Sandbox Code Playgroud)

文档:
https://github.com/symfony/symfony/blob/master/UPGRADE-2.5.md#form https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#form(在底部:The method Form::getErrorsAsString() was removed)

  • @AhadAli它是一个递归函数,因此当您将代码片段放在需要此功能的类中时,它将能够自行调用.您的"修复"将阻止您访问嵌套表单.它适用于其他37个人,它也适合你;) (3认同)

Ico*_*ood 47

以下是适合我的解决方案.此函数位于控制器中,将返回所有错误消息和导致它们的字段的结构化数组.

Symfony 2.0:

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();
    foreach ($form->getErrors() as $key => $error) {
        $template = $error->getMessageTemplate();
        $parameters = $error->getMessageParameters();

        foreach($parameters as $var => $value){
            $template = str_replace($var, $value, $template);
        }

        $errors[$key] = $template;
    }
    if ($form->hasChildren()) {
        foreach ($form->getChildren() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

Symfony 2.1和更新版本:

private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();

    if ($form->hasChildren()) {
        foreach ($form->getChildren() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    } else {
        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }   
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

  • @SalmanPK Twig在上面的代码中没有被引用.我不相信我理解你的评论. (9认同)
  • 改进了https://gist.github.com/2011671,但仍然不是我想要的.我希望数组键是字段名称,但它们不是. (5认同)
  • 他们仍然说Symfony与Twig无关.哇! (5认同)

Oli*_*ler 34

使用Validator获取特定实体的错误

if( $form->isValid() )
{
    // ...
}
else
{
    // get a ConstraintViolationList
    $errors = $this->get('validator')->validate( $user );

    $result = '';

    // iterate on it
    foreach( $errors as $error )
    {
        // Do stuff with:
        //   $error->getPropertyPath() : the field that caused the error
        //   $error->getMessage() : the error message
    }
}
Run Code Online (Sandbox Code Playgroud)

API参考:

  • 我不确定这是一个分别验证每个实体的好方法.如果您有复杂的分层形式怎么办?第二个问题是验证发生两次. (4认同)
  • @SlavaFominII - "第二个问题是验证发生了两次" - 好的,没有什么能够刷新!之后的错误列表相同! (3认同)

Ced*_*edo 19

为了得到正确的(可翻译的)消息,目前正在使用SF 2.6.3,这是我的最终功能(因为上面的任何一个似乎都不再起作用):

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, false) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->current()->getMessage());
        $errors[] = $error->current()->getMessage();
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

因为Form :: getErrors()方法现在返回FormErrorIterator的一个实例,除非你将第二个参数($ flatten)切换为true.(然后它将返回一个FormError实例,你必须直接调用getMessage()方法,而不使用current()方法:

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, true) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->getMessage());
        $errors[] = $error->getMessage();
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

)

实际上,最重要的是将第一个参数设置为true以获取错误.将第二个参数($ flatten)保留为其默认值(true)将返回FormError实例,而当设置为false时它将返回FormErrorIterator实例.


Tjo*_*rie 15

对于我的flash消息,我很满意 $form->getErrorsAsString()

编辑(来自Benji_X80):用于SF3 $form->getErrors(true, false);

  • 我知道这是一个旧的答案,但供将来参考:`这种方法只应用于帮助调试表格.([来源](https://github.com/symfony/symfony/blob/master/src/Symfony/组件/表格/ form.php的)) (3认同)

stw*_*twe 15

symfony 2.1和更新的函数,没有任何不推荐使用的函数:

/**
 * @param \Symfony\Component\Form\Form $form
 *
 * @return array
 */
private function getErrorMessages(\Symfony\Component\Form\Form $form)
{
    $errors = array();

    if ($form->count() > 0) {
        foreach ($form->all() as $child) {
            /**
             * @var \Symfony\Component\Form\Form $child
             */
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    } else {
        /**
         * @var \Symfony\Component\Form\FormError $error
         */
        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }
    }

    return $errors;
}
Run Code Online (Sandbox Code Playgroud)


Anj*_*lva 5

对于Symfony 3.2及更高版本使用此,

public function buildErrorArray(FormInterface $form)
{
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = (string) $child->getErrors(true, false);
        }
    }
    return $errors;
}
Run Code Online (Sandbox Code Playgroud)

如果您想删除每个错误描述文本中烦人的“错误: ”文本,请使用str_replace 。

$errors[$child->getName()] = str_replace('ERROR:', '', (string) $child->getErrors(true, false));
Run Code Online (Sandbox Code Playgroud)