Symfony形式:如何准确地知道哪个字段导致错误

时间:2016-12-05 14:34:38

标签: php forms validation symfony

我必须在Symfony表单验证上修复一个问题,它由30个子表单组成,每个子表单由3个实体组成,每个实体有大约20-25个字段。所以这个单一的表单包含1800多个字段: - (。

在验证时,编写这个丑陋形式的开发人员会在一行中检查它:

if ($form->isValid()) {
    [...]
}

如果表单无效,在twig Template中,他只写了:

{{ form_errors(form) }}

因此,如果我使用当前值加载表单,并在不进行任何修改的情况下提交表单,则使用相同Symfony默认消息的验证faild重复两次:

  

此值不应为空白。

     

此值不应为空白。

但是我不知道1800多个字段中的哪一个会导致错误,而且我还没有找到如何向Symfony询问给定错误,这是造成错误的字段。

我如何知道哪个字段导致了错误?

编辑 :我遵循了亚历山大的建议并且:

$errors = $form->getErrors() ;
foreach($errors as $key => $error) {
    var_dump($error);
}

只给了我两次:

class Symfony\Component\Form\FormError#1750 (3) {
    protected $messageTemplate => string(31) "This value should not be blank."
    protected $messageParameters => array(0) {}
    protected $messagePluralization => NULL
}

不知道它发生在哪里。

3 个答案:

答案 0 :(得分:1)

上做一个foreach
$form

参见\ vendor \ symfony \ symfony \ src \ Symfony \ Component \ Form \ Form.php - > getErrors

示例:

        foreach ($form as $child) {
            /** @var FormInterface $child */
            if ($child->isSubmitted() && $child->isValid()) {
                continue;
            }

            $iterator = $child->getErrors(true, $flatten);

            if (0 === count($iterator)) {
                continue;
            }
            $child->getName(); // here is the name of field

            if ($flatten) {
                foreach ($iterator as $error) {
                    $errors[] = $error;
                }
            } else {
                $errors[] = $iterator;
            }
            var_dump($errors); // here are the errors of that field
        }

答案 1 :(得分:1)

我不会完全回答你的问题,即使我明白你想要什么以及你想做什么,我会建议你另一种(也许更好)的方式。

您的错误消息This value should not be blank Symfony默认错误消息,它是针对anotations @Assert\NotBlank的Doctrine默认错误消息即可。当然,您可以为实体上使用的每个字段自定义此错误消息。只需以这种方式添加括号:

/**
 * @var \DateTime $startDate
 *
 * @Assert\NotBlank(message="The start date should not be blank/is mandatory.")
 * @ORM\Column(name="startDate", type="date", nullable = false)
 */
private $startDate;

我知道你正在处理别人的代码,有很多实体和字段,但是如果你花时间来替换大多数默认消息,它可以为你现在和以后节省很多时间。

答案 2 :(得分:0)

对于Symfony 4.x +(可能适用于较低版本)。

// $form = $this->createForm(SomeType::class);
// $form->submit($data);
// if (!$form->isValid()) {
//     var_dump($this->getErrorsFromForm($form));
// }

private function getErrorsFromForm(FormInterface $form, bool $child = false): array
{
    $errors = [];

    foreach ($form->getErrors() as $error) {
        if ($child) {
            $errors[] = $error->getMessage();
        } else {
            $errors[$error->getOrigin()->getName()][] = $error->getMessage();
        }
    }

    foreach ($form->all() as $childForm) {
        if ($childForm instanceof FormInterface) {
            if ($childErrors = $this->getErrorsFromForm($childForm, true)) {
                $errors[$childForm->getName()] = $childErrors;
            }
        }
    }

    return $errors;
}