63

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

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

$form->isValid() // returns false

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

所以,我没有form_errors(form)在我的树枝模板上使用任何东西(这看起来很正常,因为$form->getErrors()返回空)

并且书面值不会以形式替换......

有人有想法吗?

4

11 回答 11

64

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

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

于 2012-06-27T19:47:01.240 回答
63

要调试表单,请使用$form->getErrorsAsString()而不是$form->getErrors().

$form->getErrorsAsString()应该只用于调试表单...它将包含每个子元素的错误,而$form->getErrors().

正如彼得所提到的,$form->getErrors()不会返回子表单的所有错误的总和。

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

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 不正确,您通常会遇到带有 CSRF 错误的 $form->getErrors()。

于 2012-12-29T09:32:49.693 回答
58

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,如果您已激活以下功能,您还可以使用(dev environment) 功能DebugBundle

dump((string) $form->getErrors());     // Main errors
dump((string) $form->getErrors(true)); // Main and child errors
于 2014-10-22T09:30:05.950 回答
18

我刚遇到同样的问题。对我来说,表格无效,但我无法通过使用$form->getErrors()or得到任何错误$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

于 2013-12-21T11:06:13.550 回答
7

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

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

清楚地看到错误。

于 2017-10-18T09:35:21.550 回答
4

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

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

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

于 2017-01-25T11:19:26.700 回答
3

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

$request = $this->get('request');
if($request->isMethod("POST")){
      $form->submit($request);
        if($form->isValid()){
        // now true
        }
}
于 2013-09-11T20:02:22.993 回答
3

是的,它是正确的,它所说的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;
}
于 2016-11-30T15:36:28.827 回答
2

如果您通过 AJAX 发送数据,您可能错过了在数据键中包含表单的名称,因此是……的“受害者”。</p>

# 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 数据(即数组)中找不到您的表单名称。

当您以通常的方式呈现表单时,其每个字段都包含您的表单名称作为其 name 属性的前缀my_form[child_field_name]

使用 ajax 时,在 datas 中添加表单名称作为前缀!

data : {
    "my_form" : {
       "field_one" : "field_one_value"
       ...
    }
}
于 2016-06-28T15:07:37.487 回答
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()) {
        ...
于 2016-12-14T05:30:44.550 回答
0

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

use Symfony\Component\Validator\Constraints as Assert;

还有这个在每个属性之上

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

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

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

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

于 2012-06-27T18:19:09.590 回答