在Symfony2中,我正在丢失错误与表单字段的关联


I'm losing the association of an error to a form field in Symfony2

我的验证看起来像

Acme'UserBundle'Entity'User:
    constraints:
        - 'Symfony'Bridge'Doctrine'Validator'Constraints'UniqueEntity: { fields:username, message: "Username already in use" }
        - 'Symfony'Bridge'Doctrine'Validator'Constraints'UniqueEntity: { fields:email, message: "Email address already in use" }
    properties:
        username:
            - NotBlank: ~
            - MinLength: { limit: 2, message: "Your username must have at least {{ limit }} characters." }
        email:
            - Email:
                message: The email "{{ value }}" is not a valid email.
                checkMX: true

我的控制器像:

$form = $this->createForm(new RegistrationType());
$form->bindRequest($request);
if ($form->isValid()) {
    //... save to db
}else{
    $errors = $form->getErrors();
    //... pass the errors back as json
}

我试图建立一个用户注册控制器是通过ajax请求提交。但是,当触发验证中的错误时,$error变量看起来像:

[2011-11-07 19:19:44] app.INFO: array (
  0 => 
  Symfony'Component'Form'FormError::__set_state(array(
     'messageTemplate' => 'Email address already in use',
     'messageParameters' => 
    array (
    ),
  )),
  1 => 
  Symfony'Component'Form'FormError::__set_state(array(
     'messageTemplate' => 'Your username must have at least {{ limit }} characters.',
     'messageParameters' => 
    array (
      '{{ value }}' => '1',
      '{{ limit }}' => 2,
    ),
  )),
) [] []

问题是我不知道错误对应于哪个字段。是否有某种方法可以找到这些数据,以便当我发送json响应时,我可以将错误消息与相关字段关联。

我认为您可以单独查询每个字段,例如:

$form->get('username')->getErrors()

你可以这样创建一个数组:

$errors['username'] = $form->get('username')->getErrors();
$errors['email'] = $form->get('email')->getErrors();

你也许可以自动化一些事情:

$fields = $form->getChildren();
foreach ( $fields as $field ) {
    $errors[$field->getName()] = $field->getErrors();
}

我认为getName函数应该返回字段名时,窗体本身的子调用。也许其他人有更有效的方法…

我认为公认的答案已经过时了,再也没有getChildren()方法了。

$errors = [];
foreach ($form->all() as $field) {
    if ($field->getErrors()->count() > 0) {
        $fieldName = $field->getName();
        $errors[$fieldName] = [];
        foreach ($field->getErrors() as $error) {
            $errors[$fieldName][] = $error->getMessage();
        }
    }
}

最后,如果你想从生成的FormView中访问表单字段,它会给你完整的输入字段名:

$errors = [];
foreach ($form->createView()->children as $field) {
    if ($field->vars['errors']->count() > 0) {
        $fieldName = $field->vars['full_name'];
        $errors[$fieldName] = [];
        foreach ($field->vars['errors'] as $error) {
            $errors[$fieldName][] = $error->getMessage();
        }
    }
}