Symfony2无效表单没有错误

时间:2012-06-26 13:58:14

标签: forms validation symfony

我遇到了Symfony2生成的CRUD表单的问题。 (使用MongoDB文档,但我不认为这是相关的)

在我的控制器的createAction()方法中,当我调试表单结果时:

$form->isValid() // returns false

$form->getErrors() // returns en empty array(0) {}

所以,我的twig模板上没有使用form_errors(form)得到任何东西(由于$form->getErrors()空返回,这看似正常)

并且书面值不会被替换为......

有没有人有想法?

11 个答案:

答案 0 :(得分:61)

要调试表单,请使用$form->getErrorsAsString()代替$form->getErrors()

$form->getErrorsAsString()应仅用于调试表单...它将包含每个子元素的错误,而不是$form->getErrors()的情况。

正如彼得所提到的那样,$form->getErrors()不会返回儿童形式的所有错误的总和。

要了解表单如何无效并让getErrors()返回一个空数组,您可以查看symfony表单类的isValid()方法。如您所见,有两种情况表单无效,第一种情况测试一般表单,第二种情况测试每种子元素。

public function isValid()
{
    //...

    //CASE I : IF CHILD ELEMENTS HAVE ERRORS, $this->errors WILL CONTAIN
    //THE ERROR ON THE CHILD ELEMENT AND NOT ON THE GENERAL 'errors' FIELD 
    //ITSELF

    if (count($this->errors) > 0) {
        return false;
    }

    //CASE II: AND THIS IS WHY WE ARE TESTING THE CHILD ELEMENTS AS WELL
    //TO CHECK WHETHER THERE ARE VALID OR NOT

    if (!$this->isDisabled()) {
        foreach ($this->children as $child) {
            if (!$child->isValid()) {
                return false;
            }
        }
    }

    return true;
}

因此,每个表单子项都可以包含错误,但$form->getErrors()本身不会返回所有错误。考虑到具有许多子元素的表单,如果CSRF不正确,通常会有$ form-> getErrors(),并出现CSRF错误。

答案 1 :(得分:60)

首先要理解的是验证是在模型上完成的,而不是表单。表单可能包含错误,但前提是它有一个映射到不验证的属性的字段。因此,如果您的表单不包含无效字段(可能是对于不在表单中的属性的NotNull断言),则不会显示错误。

第二件事是$form->getErrors()只会显示该级别的错误,每个表单子级都可以包含自己的错误。因此,如果要检查错误,则应遍历字段并在每个字段上调用getErrors。 Form类上的getErrors方法可能会欺骗这种方式。

答案 2 :(得分:50)

Symfony 2.6的更新

所以取决于你Symfony2版本:

die($form->getErrorsAsString());

开始,getErrorsAsString()函数已弃用(将在Symfony3中删除),您应该使用以下方法:

die((string) $form->getErrors());     // Main errors
die((string) $form->getErrors(true)); // Main and child errors

开始,如果您已激活dump,则还可以使用DebugBundle(开发环境)功能:

dump((string) $form->getErrors());     // Main errors
dump((string) $form->getErrors(true)); // Main and child errors

答案 3 :(得分:18)

我遇到了同样的问题。对我来说,表单无效,但使用$form->getErrors()$form->getErrorsAsString()我无法收到任何错误。我后来发现忘记将CSRF令牌传递给表单,因此不会提交,$form->handleRequest($request)什么也没做(没有验证)。当我看到@ pit的答案时,我试图使用

$form->submit($request);

$form->getErrorsAsString();

它返回了一个错误:

  

错误:CSRF令牌无效。请尝试重新提交表单。

以下是Symfony2文档中的一些解释:http://symfony.com/doc/current/book/forms.html#handling-form-submissions

答案 4 :(得分:5)

对于Symfony(> = 3.2 - 4),您可以使用:

foreach($form->getErrors(true, false) as $er) {
    print_r($er->__toString());
}

显然可以看到错误。

答案 5 :(得分:4)

从Symfony 3开始,根据文档,你应该使用新的实现:

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

这会将所有错误作为一个字符串返回。

答案 6 :(得分:3)

对我来说,即使我有一个提交按钮,表单也没有提交。 我添加了解决问题的代码

$request = $this->get('request');
if($request->isMethod("POST")){
      $form->submit($request);
        if($form->isValid()){
        // now true
        }
}

答案 7 :(得分:2)

如果您通过AJAX发送数据,您可能错过了在数据键上包含表单的名称,因此是#34;受害者" ......

# line 100 of Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php 
// Don't submit the form if it is not present in the request

这意味着,在尝试处理请求时,请求处理机制未在GET / POST数据中找到您的表单名称(表示为数组)。

以常规方式呈现表单时,其每个字段都将表单的名称作为其名称属性my_form[child_field_name]的前缀。

使用ajax时,请将表单的名称添加为数据中的前缀!

data : {
    "my_form" : {
       "field_one" : "field_one_value"
       ...
    }
}

答案 8 :(得分:2)

是 这是正确的,它说的是什么 Peter Kruithof 在SF 2.8中,这是我的功能,以获取字段的错误

 private function getErrorsForm(\Symfony\Component\Form\Form $form)
{
    $response =  array();

    foreach ($form as $child) {
         foreach ($child->getErrors(true) as $error) {
            $response[$child->getName()][] = $error->getMessage();
         }
    }

    return $response;
}

答案 9 :(得分:1)

我遇到了这个错误,发现我忘记了"处理"请求。确保你有这个......

public function editAction(Request $request)
{
    $form = $this->createForm(new CustomType(),$dataObject);
    /**  This next line is the one I'm talking about... */
    $form->handleRequest($request);
    if ($request->getMethod() == "POST") {
        if ($form->isValid()) {
        ...

答案 10 :(得分:0)

看起来您有验证问题。表单未在提交时验证。我将假设您使用Annotations进行验证。确保在实体的顶部有这个。

use Symfony\Component\Validator\Constraints as Assert;

以及每个属性上面的

/**      
 * @Assert\NotBlank()      
 */

NotBlank()可以更改为任何约束以满足您的需求。

有关验证的更多信息,请访问: http://symfony.com/doc/current/book/validation.html

有关Assert约束的更多信息,请访问: http://symfony.com/doc/current/book/validation.html#constraints