Symfony2 : How to get form validation errors after

2020-01-24 03:45发布

Here's my saveAction code (where the form passes the data to)

public function saveAction()
{
    $user = OBUser();

    $form = $this->createForm(new OBUserType(), $user);

    if ($this->request->getMethod() == 'POST')
    {
        $form->bindRequest($this->request);
        if ($form->isValid())
            return $this->redirect($this->generateUrl('success_page'));
        else
            return $this->redirect($this->generateUrl('registration_form'));
    } else
        return new Response();
}

My question is: how do I get the errors if $form->isValid() returns false?

标签: symfony
19条回答
贪生不怕死
2楼-- · 2020-01-24 03:49

Translated Form Error Messages (Symfony2.1)

I have been struggling a lot to find this information so I think it's definitely worth adding a note on translation of form errors.

@Icode4food answer will return all errors of a form. However, the array that is returned does not take into account either message pluralization or translation.

You can modify the foreach loop of @Icode4food answer to have a combo:

  • Get all errors of a particular form
  • Return a translated error
  • Take pluralization into account if necessary

Here it is:

foreach ($form->getErrors() as $key => $error) {

   //If the message requires pluralization
    if($error->getMessagePluralization() !== null) {
        $errors[] = $this->container->get('translator')->transChoice(
            $error->getMessage(), 
            $error->getMessagePluralization(), 
            $error->getMessageParameters(), 
            'validators'
            );
    } 
    //Otherwise, we do a classic translation
    else {
        $errors[] = $this->container->get('translator')->trans(
            $error->getMessage(), 
            array(), 
            'validators'
            );
    }
}

This answer has been put together from 3 different posts:

查看更多
叼着烟拽天下
3楼-- · 2020-01-24 03:51

Use the Validator to get the errors for a specific entity

if( $form->isValid() )
{
    // ...
}
else
{
    // get a ConstraintViolationList
    $errors = $this->get('validator')->validate( $user );

    $result = '';

    // iterate on it
    foreach( $errors as $error )
    {
        // Do stuff with:
        //   $error->getPropertyPath() : the field that caused the error
        //   $error->getMessage() : the error message
    }
}

API reference:

查看更多
Bombasti
4楼-- · 2020-01-24 03:52

You can also use the validator service to get constraint violations:

$errors = $this->get('validator')->validate($user);
查看更多
太酷不给撩
5楼-- · 2020-01-24 03:54

For Symfony 2.1 onwards for use with Twig error display I altered the function to add a FormError instead of simply retrieving them, this way you have more control over errors and do not have to use error_bubbling on each individual input. If you do not set it in the manner below {{ form_errors(form) }} will remain blank:

/**
 * @param \Symfony\Component\Form\Form $form
 *
 * @return void
 */
private function setErrorMessages(\Symfony\Component\Form\Form $form) {      

    if ($form->count() > 0) {
        foreach ($form->all() as $child) {
            if (!$child->isValid()) {
                if( isset($this->getErrorMessages($child)[0]) ) {
                    $error = new FormError( $this->getErrorMessages($child)[0] );
                    $form->addError($error);
                }
            }
        }
    }

}
查看更多
▲ chillily
6楼-- · 2020-01-24 03:54

For Symfony 2.1:

This is my final solution putting in together many others solutions:

protected function getAllFormErrorMessages($form)
{
    $retval = array();
    foreach ($form->getErrors() as $key => $error) {
        if($error->getMessagePluralization() !== null) {
            $retval['message'] = $this->get('translator')->transChoice(
                $error->getMessage(), 
                $error->getMessagePluralization(), 
                $error->getMessageParameters(), 
                'validators'
            );
        } else {
            $retval['message'] = $this->get('translator')->trans($error->getMessage(), array(), 'validators');
        }
    }
    foreach ($form->all() as $name => $child) {
        $errors = $this->getAllFormErrorMessages($child);
        if (!empty($errors)) {
           $retval[$name] = $errors; 
        }
    }
    return $retval;
}
查看更多
欢心
7楼-- · 2020-01-24 03:55

If you're using custom validators, Symfony doesn't return errors generated by those validators in $form->getErrors(). $form->getErrorsAsString() will return all the errors you need, but its output is unfortunately formatted as a string, not an array.

The method you use to get all the errors (regardless of where they came from), depends on which version of Symfony you're using.

Most of the suggested solutions involve creating a recursive function that scans all child forms, and extracts the relevant errors into one array. Symfony 2.3 doesn't have the $form->hasChildren() function, but it does have $form->all().

Here is a helper class for Symfony 2.3, which you can use to extract all errors from any form. (It's based on code from a comment by yapro on a related bug ticket in Symfony's github account.)

namespace MyApp\FormBundle\Helpers;

use Symfony\Component\Form\Form;

class FormErrorHelper
{
    /**
     * Work-around for bug where Symfony (2.3) does not return errors from custom validaters,
     * when you call $form->getErrors().
     * Based on code submitted in a comment here by yapro:
     * https://github.com/symfony/symfony/issues/7205
     *
     * @param Form $form
     * @return array Associative array of all errors
     */
    public function getFormErrors($form)
    {
        $errors = array();

        if ($form instanceof Form) {
            foreach ($form->getErrors() as $error) {
                $errors[] = $error->getMessage();
            }

            foreach ($form->all() as $key => $child) {
                /** @var $child Form */
                if ($err = $this->getFormErrors($child)) {
                    $errors[$key] = $err;
                }
            }
        }

        return $errors;
    }
}

Calling code:

namespace MyApp\ABCBundle\Controller;

use MyApp\FormBundle\Helpers;

class MyController extends Controller
{
    public function XYZAction()
    {
        // Create form.

        if (!$form->isValid()) {
            $formErrorHelper = new FormErrorHelper();
            $formErrors = $formErrorHelper->getFormErrors($form);

            // Set error array into twig template here.
        }
    }

}
查看更多
登录 后发表回答