当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Symfony2:如何在将请求绑定到表单后获取表单验证错误》经验,为你挑选了7个好方法。

这是我的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();
}

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



1> nefo_x..:

您有两种可能的方法:

不要在出错时重定向用户并{{ form_errors(form) }}在模板文件中显示

访问错误数组为 $form->getErrors()


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

2> Flip..:

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;
}

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

$string = var_export($this->getErrorMessages($form), true);

Symfony 2.5/3.0:

$string = (string) $form->getErrors(true, false);

文档:
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> Icode4food..:

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

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;
}

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;
}


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

4> Olivier 'Ölb..:

使用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
    }
}

API参考:

ConstraintViolationList

ConstraintViolation


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

5> 小智..:

为了得到正确的(可翻译的)消息,目前正在使用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;
}

因为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;
}

)

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



6> Tjorriemorri..:

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

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


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

7> stwe..:

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;
}

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有