Symfony2无效形式没有错误
Posted
技术标签:
【中文标题】Symfony2无效形式没有错误【英文标题】:Symfony2 invalid form without errors 【发布时间】:2012-06-27 20:51:07 【问题描述】:我遇到了 Symfony2 生成的 CRUD 表单的问题。 (使用 MongoDB Documents,但我认为这无关)
在我的控制器的 createAction() 方法中,当我调试表单结果时:
$form->isValid() // returns false
$form->getErrors() // returns en empty array(0)
所以,我在我的树枝模板上使用 form_errors(form)
没有得到任何东西(这似乎很正常,因为 $form->getErrors()
为空返回)
而且写出来的值不会换成表格...
有人有想法吗?
【问题讨论】:
您能否编辑您的问题以包含您的validation.xml 或您的验证注释。 【参考方案1】:您的验证出现问题。表单在提交时未验证。我将假设您正在使用注释进行验证。确保你在实体的顶部有这个。
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
【讨论】:
我正在使用 MongoDB,所以我没有实体,只有文档。并且在我的文档类文件中已经准备好这一行,否则我会收到另一个 php 错误或警告;)我想我的错误来自这个注释,因为我的表单上有文件字段......我稍后再试。谢谢!【参考方案2】:首先要了解的是验证是在模型上完成的,而不是在表单上完成的。表单可以包含错误,但前提是它有一个映射到未验证的属性的字段。因此,如果您的表单不包含无效字段(可能是对不在表单中的属性的NotNull
断言),它将不会显示错误。
第二件事是$form->getErrors()
只会显示该级别的错误,每个表单子级都可以包含自己的错误。因此,如果您想检查错误,您应该遍历字段并在每个字段上调用 getErrors。 Form 类上的 getErrors
方法可能具有这种欺骗性。
【讨论】:
我不知道,谢谢,我想我找到了答案。我试试看! 如果您这样做了,请将其标记为已接受的答案,以便其他有此问题的人也可以从中受益。 我遇到了同样的问题,我使用 createForm 并有一个类型添加一个文本字段。为什么它会创建一个子窗体?!我只有一个文本字段... 您还可以通过传递 'true' 作为第一个参数来获取子错误:$form->getErrors(true)【参考方案3】:要调试表单,请使用$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 不正确,您通常会遇到带有 CSRF 错误的 $form->getErrors()。
【讨论】:
非常感谢这个答案。如果没有它,我将不得不花费大量时间来调试无效字段。 $form->getErrorsAsString() 在 Symfony 2.5+ 中被弃用 非常好的点@ChristoKiwi!如果您愿意,请随时更新答案! 对于弃用警告,请改用getErrors()
,他们还说要转换为字符串,我结束了使用(string)$form->getErrors(true);
对于 Symfony 3.2,将错误作为字符串获取,如下所示:$form->getErrors(true, false);
【参考方案4】:
对我来说,表单没有提交,即使我有一个提交按钮。 我添加了解决问题的代码
$request = $this->get('request');
if($request->isMethod("POST"))
$form->submit($request);
if($form->isValid())
// now true
【讨论】:
看起来很奇怪,同一个页面不是有好几个表格吗? 也许你错过了 $form->handleRequest($this->getRequest()); 指令。它应该在 isValid() 检查之前调用。【参考方案5】:我也遇到了同样的问题。对我来说,该表单无效,但使用 $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
【讨论】:
【参考方案6】:Symfony 2.6 更新
所以取决于你的 Symfony2 版本:
symfony2.3
die($form->getErrorsAsString());
截至symfony2.5,getErrorsAsString()
函数已被弃用(将在 Symfony3 中删除),您应该使用以下方法:
die((string) $form->getErrors()); // Main errors
die((string) $form->getErrors(true)); // Main and child errors
从symfony2.6开始,如果你激活了DebugBundle
,也可以使用dump
(开发环境)功能:
dump((string) $form->getErrors()); // Main errors
dump((string) $form->getErrors(true)); // Main and child errors
【讨论】:
谢谢,没注意到! 这个帮助我解决了我的问题,谢谢! (使用 Symfony 2.8) $form->getErrors(true) 不错! $form->getErrors(true) 在 symfony 3.4 上也是如此。不知道“深度”参数,它显示来自孩子的错误。【参考方案7】:如果您通过 AJAX 发送数据,您可能没有在数据键中包含表单名称,因此是……的“受害者”
# 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】:是的 这是正确的,它说的是 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;
【讨论】:
或者:$form->getErrors(true)【参考方案9】:我遇到了这个错误,发现我忘记“处理”请求。确保你有那个...
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】:根据文档,从 Symfony 3 开始,您应该使用新的实现:
$errors = (string) $form->getErrors(true, false);
这会将所有错误作为一个字符串返回。
【讨论】:
【参考方案11】:对于 Symfony (>= 3.2 - 4),您可以使用:
foreach($form->getErrors(true, false) as $er)
print_r($er->__toString());
清楚地看到错误。
【讨论】:
我认为直接使用“魔术”__toString()
方法不是一个好习惯。正如亚当已经建议的那样,更容易将对象直接转换为字符串。
当然可以,但是,如果您想在没有太多编码的情况下查看问题所在,它会有所帮助。以上是关于Symfony2无效形式没有错误的主要内容,如果未能解决你的问题,请参考以下文章
学说 symfony2 错误:Cocina\ComprasBundle\Entity\Productos 类没有名为proveedores 的关联