Symfony2: Como obter erros de validação de formulário após vincular a solicitação ao formulário

110

Este é o meu saveActioncódigo (para onde o formulário passa os dados)

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();
}

Minha pergunta é: como faço para obter os erros se $form->isValid()retorna false?

putolaruan
fonte

Respostas:

117

Você tem duas maneiras possíveis de fazer isso:

  • não redirecione o usuário em caso de erro e exiba {{ form_errors(form) }}no arquivo de modelo
  • acessar array de erro como $form->getErrors()
nefo_x
fonte
22
Eu fiz a segunda coisa que você sugeriu, mas form-> getErrors () retorna um array em branco.
putolaruan de
2
Eu também fiz o primeiro (w / php templates <? Php echo $ view ['form'] -> erros ($ form)?>) Mas ainda está vazio!
putolaruan de
59
@mives Você deve definir error_bubblingcomo verdadeiro em seu tipo de formulário, definindo explicitamente a opção para cada campo.
kgilden
5
Se você estiver usando validadores customizados, Symfony não retorna erros gerados por aqueles validadores em $ form-> getErrors ().
Jay Sheth
13
Você também pode $form->getErrors(true)incluir erros em formulários filhos
Chris,
103

Symfony 2.3 / 2.4:

Esta função obtém todos os erros. Aqueles no formulário como "O token CSRF é inválido. Tente reenviar o formulário." bem como erros adicionais nos filhos do formulário que não apresentam erros de bolha.

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = $this->getErrorMessages($child);
        }
    }

    return $errors;
}

Para obter todos os erros como uma string:

$string = var_export($this->getErrorMessages($form), true);

Symfony 2.5 / 3.0:

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

Documentos:
https://github.com/symfony/symfony/blob/master/UPGRADE-2.5.md#form https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#form (em a parte inferior: The method Form::getErrorsAsString() was removed)

Giro
fonte
1
Esta parece ser a resposta mais correta para o Symfony 2.4 atual.
Slava Fomin II
@Flip funciona perfeitamente em 2,5
iarroyo
1
Ótima resposta, MAS $errors[$child->getName()] = $this->getErrorMessages($child);estava lançando uma exceção, pois getErrorMessages estava faltando no componente Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller . Então eu o substituí por$form_errors[$child->getName()] = $child->getErrorsAsString();
Ahad Ali
3
@AhadAli é uma função recursiva, então quando você coloca o trecho de código na classe onde você precisa dessa funcionalidade, ele será capaz de chamar a si mesmo. Sua "correção" impedirá que você alcance os formulários aninhados. Funcionou para outras 37 pessoas, deve funcionar para você também;)
Flip
@Flip Ah, desculpe minha má, eu estava apenas olhando $this->getErrorMessages()e pensei que fosse chamado diretamente de um controlador e parte da API Symfony.
Ahad Ali de
47

Abaixo está a solução que funcionou para mim. Esta função está em um controlador e retornará um array estruturado de todas as mensagens de erro e o campo que as causou.

Symfony 2.0:

private function getErrorMessages(\Symfony\Component\Form\Form $form) {
    $errors = array();
    foreach ($form->getErrors() as $key => $error) {
        $template = $error->getMessageTemplate();
        $parameters = $error->getMessageParameters();

        foreach($parameters as $var => $value){
            $template = str_replace($var, $value, $template);
        }

        $errors[$key] = $template;
    }
    if ($form->hasChildren()) {
        foreach ($form->getChildren() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    }

    return $errors;
}

Symfony 2.1 e mais recente:

private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();

    if ($form->hasChildren()) {
        foreach ($form->getChildren() as $child) {
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    } else {
        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }   
    }

    return $errors;
}
Icode4food
fonte
5
Gist.github.com/2011671 aprimorado, mas ainda não é o que eu quero. Eu quero que as chaves de array sejam nomes de campo, mas não são.
umpirsky
9
@SalmanPK Twig não é referenciado em nenhum lugar no código acima. Eu não acredito que entendo seu comentário.
Icode4food
1
Aqui está uma correção para a essência anterior, isso funciona no Symfony 2.1.7. gist.github.com/WishCow/5101428
K. Norbert
Parece que há um erro de digitação $this->getFormErrorsdeve ser $this->getErrorMessagesna sua amostra em Symfony2.1
Mick
@umpirsky Para obter o nome do campo, obtive o seguinte: $ child-> getConfig () -> getOptions () ['label'] Levei uma eternidade para descobrir ...
jsgoupil
35

Use o validador para obter os erros de uma entidade específica

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
    }
}

Referência da API:

Olivier 'Ölbaum' Scherler
fonte
Obrigado, o que eu precisava +1
Phill Pafford
4
Não tenho certeza se é uma boa abordagem para validar cada entidade separadamente. E se você tiver uma forma hierárquica complexa? O segundo problema é que a validação acontece duas vezes.
Slava Fomin II
3
@SlavaFominII - "O segundo problema é que a validação acontece duas vezes" - Bom ponto, nada é atualizado! A mesma lista de erros depois!
BentCoder
20

Para obter mensagens adequadas (traduzíveis), atualmente usando SF 2.6.3, aqui está minha função final (já que nenhuma das anteriores parece funcionar mais):

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, false) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->current()->getMessage());
        $errors[] = $error->current()->getMessage();
    }

    return $errors;
}

já que o método Form :: getErrors () agora retorna uma instância de FormErrorIterator , a menos que você altere o segundo argumento ($ flatten) para true . (Em seguida, ele retornará uma instância FormError e você terá que chamar o método getMessage () diretamente, sem o método current ():

 private function getErrorMessages(\Symfony\Component\Form\Form $form) {      
    $errors = array();
    foreach ($form->getErrors(true, true) as $error) {
        // My personnal need was to get translatable messages
        // $errors[] = $this->trans($error->getMessage());
        $errors[] = $error->getMessage();
    }

    return $errors;
}

)

A coisa mais importante é definir o primeiro argumento como verdadeiro para obter os erros. Deixar o segundo argumento ($ flatten) com seu valor padrão ( true ) retornará instâncias FormError , enquanto retornará instâncias FormErrorIterator quando definido como false.

Cedo
fonte
Legal, usando as mesmas coisas.
Danificado orgânico
não é? :) @KidBinary
Cedo
Absolutamente lindo, companheiro
:)
A melhor opção é: $ errors = array_map (function ($ item) {return $ item-> current () -> getMessage ();}, $ campaignForm-> getErrors (true, false));
Enrique Quero
Boa solução para Symfony 2.7
Yann Chabot
16

Para minhas mensagens flash, fiquei feliz com $form->getErrorsAsString()

Editar (de Benji_X80): Para uso em SF3 $form->getErrors(true, false);

Tjorriemorrie
fonte
3
Eu sei que é uma resposta antiga, mas para referência futura: This method should only be used to help debug a form.( fonte )
cheesemacfly
getErrorsAsString () está obsoleto no 3.0, use: $ form-> getErrors (true, false);
Benji_X80
15

A função para symfony 2.1 e mais recente, sem qualquer função obsoleta:

/**
 * @param \Symfony\Component\Form\Form $form
 *
 * @return array
 */
private function getErrorMessages(\Symfony\Component\Form\Form $form)
{
    $errors = array();

    if ($form->count() > 0) {
        foreach ($form->all() as $child) {
            /**
             * @var \Symfony\Component\Form\Form $child
             */
            if (!$child->isValid()) {
                $errors[$child->getName()] = $this->getErrorMessages($child);
            }
        }
    } else {
        /**
         * @var \Symfony\Component\Form\FormError $error
         */
        foreach ($form->getErrors() as $key => $error) {
            $errors[] = $error->getMessage();
        }
    }

    return $errors;
}
stwe
fonte
Eu ia postar uma nova resposta para esta postagem, mas você parecia ter me vencido. Tive que examinar o código-fonte para descobrir por que as chamadas de método não foram encontradas.
Dr.Knowitall
Percebi que isso não extrai erros de itens que têm o borbulhamento de erro definido como verdadeiro. SF2.4
kinghfb
@stwe qual é o propósito da primeira IFdeclaração? Por que é mutuamente exclusivo? Tanto quanto eu posso ver: o formulário pode ter seus próprios erros, assim como filhos.
Slava Fomin II
4

Mensagens de erro de formulário traduzido (Symfony2.1)

Tenho lutado muito para encontrar essas informações, então acho que definitivamente vale a pena adicionar uma nota sobre a tradução de erros de formulário.

@Icode4foodresposta retornará todos os erros de um formulário. No entanto, a matriz retornada não leva em consideração a pluralização ou a tradução da mensagem .

Você pode modificar o loop foreach de @Icode4foodresposta para ter uma combinação:

  • Obtenha todos os erros de um formulário específico
  • Retorne um erro traduzido
  • Leve em consideração a pluralização, se necessário

Aqui está:

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'
            );
    }
}

Esta resposta foi reunida a partir de 3 postagens diferentes:

Mick
fonte
Apenas tentei sua versão e foi embora Fatal Error: Call to undefined method Symfony\Component\Form\FormError::getMessagePluralization(). Estou suspeitando que isso é apenas para Symfony 2.1?
Czar Pino de
4

SYMFONY 3.X

Outros métodos SF 3.X fornecidos aqui não funcionaram para mim porque eu poderia enviar dados vazios ao formulário (mas eu tenho restrições NotNull / NotBlanck). Nesse caso, a string de erro seria assim:

string(282) "ERROR: This value should not be blank.
ERROR: This value should not be blank.
ERROR: This value should not be blank.
ERROR: This value should not be blank.
ERROR: This value should not be blank.
ERROR: This value should not be null.
name:
    ERROR: This value should not be blank.
"

O que não é muito útil. Então eu fiz isso:

public function buildErrorArray(FormInterface $form)
{
    $errors = [];

    foreach ($form->all() as $child) {
        $errors = array_merge(
            $errors,
            $this->buildErrorArray($child)
        );
    }

    foreach ($form->getErrors() as $error) {
        $errors[$error->getCause()->getPropertyPath()] = $error->getMessage();
    }

    return $errors;
}

Que retornaria isso:

array(7) {
  ["data.name"]=>
  string(31) "This value should not be blank."
  ["data.street"]=>
  string(31) "This value should not be blank."
  ["data.zipCode"]=>
  string(31) "This value should not be blank."
  ["data.city"]=>
  string(31) "This value should not be blank."
  ["data.state"]=>
  string(31) "This value should not be blank."
  ["data.countryCode"]=>
  string(31) "This value should not be blank."
  ["data.organization"]=>
  string(30) "This value should not be null."
}
Sbouba
fonte
3

Você também pode usar o serviço de validador para obter violações de restrição:

$errors = $this->get('validator')->validate($user);
Antoinet
fonte
6
Isso validará o objeto, mas não o formulário. Se, por exemplo, o token CRSF fosse a causa do erro, a mensagem não seria incluída.
Icode4food
3

Mensagens de erro de formulário traduzido (Symfony2.3)

Minha versão para resolver o problema:

/src/Acme/MyBundle/Resources/config/services.yml

services:
    form_errors:
        class: Acme\MyBundle\Form\FormErrors

/src/Acme/MyBundle/Form/FormErrors.php

<?php
namespace Acme\MyBundle\Form;

class FormErrors
{
    public function getArray(\Symfony\Component\Form\Form $form)
    {
        return $this->getErrors($form);
    }

    private function getErrors($form)
    {
        $errors = array();

        if ($form instanceof \Symfony\Component\Form\Form) {

            // соберем ошибки элемента
            foreach ($form->getErrors() as $error) {

                $errors[] = $error->getMessage();
            }

            // пробежимся под дочерним элементам
            foreach ($form->all() as $key => $child) {
                /** @var $child \Symfony\Component\Form\Form */
                if ($err = $this->getErrors($child)) {
                    $errors[$key] = $err;
                }
            }
        }

        return $errors;
    }
}

/src/Acme/MyBundle/Controller/DefaultController.php

$form = $this->createFormBuilder($entity)->getForm();
$form_errors = $this->get('form_errors')->getArray($form);
return new JsonResponse($form_errors);

No Symfony 2.5 você pode obter todos os erros de campos muito facilmente:

    $errors = array();
    foreach ($form as $fieldName => $formField) {
        foreach ($formField->getErrors(true) as $error) {
            $errors[$fieldName] = $error->getMessage();
        }
    }
Lebnik
fonte
3

Para Symfony 3.2 e acima, use isso,

public function buildErrorArray(FormInterface $form)
{
    $errors = array();

    foreach ($form->getErrors() as $key => $error) {
        if ($form->isRoot()) {
            $errors['#'][] = $error->getMessage();
        } else {
            $errors[] = $error->getMessage();
        }
    }

    foreach ($form->all() as $child) {
        if (!$child->isValid()) {
            $errors[$child->getName()] = (string) $child->getErrors(true, false);
        }
    }
    return $errors;
}

Use str_replace se quiser se livrar do irritante texto ' Error: ' em cada texto de descrição de erro.

$errors[$child->getName()] = str_replace('ERROR:', '', (string) $child->getErrors(true, false));
Anjana Silva
fonte
2

Se você estiver usando validadores personalizados, o Symfony não retorna erros gerados por esses validadores em $form->getErrors(). $form->getErrorsAsString()retornará todos os erros de que você precisa, mas sua saída infelizmente está formatada como uma string, não uma matriz.

O método que você usa para obter todos os erros (independentemente de onde eles vieram), depende de qual versão do Symfony você está usando.

A maioria das soluções sugeridas envolve a criação de uma função recursiva que verifica todos os formulários filho e extrai os erros relevantes em um array. Symfony 2.3 não tem a $form->hasChildren()função, mas tem $form->all().

Aqui está uma classe auxiliar para Symfony 2.3, que você pode usar para extrair todos os erros de qualquer formulário. (É baseado no código de um comentário de yapro em um tíquete de bug relacionado na conta github do Symfony.)

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;
    }
}

Código de chamada:

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.
        }
    }

}
Jay Sheth
fonte
2

Com base na resposta de @Jay Seth, fiz uma versão da classe FormErrors especialmente para Formulários Ajax:

// src/AppBundle/Form/FormErrors.php
namespace AppBundle\Form;

class FormErrors
{

    /**
     * @param \Symfony\Component\Form\Form $form
     *
     * @return array $errors
     */
    public function getArray(\Symfony\Component\Form\Form $form)
    {
        return $this->getErrors($form, $form->getName());
    }

    /**
     * @param \Symfony\Component\Form\Form $baseForm
     * @param \Symfony\Component\Form\Form $baseFormName
     *
     * @return array $errors
     */
    private function getErrors($baseForm, $baseFormName) {
        $errors = array();
        if ($baseForm instanceof \Symfony\Component\Form\Form) {
            foreach($baseForm->getErrors() as $error) {
                $errors[] = array(
                    "mess"      => $error->getMessage(),
                    "key"       => $baseFormName
                );
            }

            foreach ($baseForm->all() as $key => $child) {
                if(($child instanceof \Symfony\Component\Form\Form)) {
                    $cErrors = $this->getErrors($child, $baseFormName . "_" . $child->getName());
                    $errors = array_merge($errors, $cErrors);
                }
            }
        }
        return $errors;
    }
}

Uso (por exemplo, em sua ação):

$errors = $this->get('form_errors')->getArray($form);

Versão Symfony: 2.8.4

Resposta JSON de exemplo:

{
    "success": false,
    "errors": [{
        "mess": "error_message",
        "key": "RegistrationForm_user_firstname"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_user_lastname"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_user_email"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_user_zipCode"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_user_password_password"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_terms"
    }, {
        "mess": "error_message2",
        "key": "RegistrationForm_terms"
    }, {
        "mess": "error_message",
        "key": "RegistrationForm_marketing"
    }, {
        "mess": "error_message2",
        "key": "RegistrationForm_marketing"
    }]
}

O objeto de erro contém o campo "chave", que é o id do elemento DOM de entrada, para que você possa preencher facilmente as mensagens de erro.

Se você tiver formulários filho dentro do pai, não se esqueça de adicionar a cascade_validationopção dentro do formulário pai setDefaults.

Ladrão
fonte
1

Para Symfony 2.1 em diante para uso com exibição de erro Twig eu alterei a função para adicionar um FormError ao invés de simplesmente recuperá-los, desta forma você tem mais controle sobre os erros e não precisa usar error_bubbling em cada entrada individual. Se você não definir da maneira abaixo {{form_errors (form)}} permanecerá em branco:

/**
 * @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);
                }
            }
        }
    }

}
País das Maravilhas Hard-Boiled
fonte
1

$ form-> getErrors () funciona para mim.

ahyong
fonte
1

Eu vim com esta solução. Ele funciona bem com o Symfony 2.4 mais recente .

Vou tentar dar algumas explicações.

Usando um validador separado

Acho uma má ideia usar validação separada para validar entidades e retornar mensagens de violação de restrição, como sugerido por outros escritores.

  1. Você precisará validar manualmente todas as entidades, especificar grupos de validação, etc., etc. Com formas hierárquicas complexas, não é nada prático e sairá do controle rapidamente.

  2. Desta forma, você validará o formulário duas vezes: uma com o formulário e outra com o validador separado. Esta é uma má ideia do ponto de vista do desempenho.

Eu sugiro iterar recursivamente o tipo de formulário com seus filhos para coletar mensagens de erro.

Usando alguns métodos sugeridos com declaração IF exclusiva

Algumas respostas sugeridas por outros autores contêm declarações IF mutuamente exclusivas como esta: if ($form->count() > 0)ou if ($form->hasChildren()).

Pelo que posso ver, todos os formulários podem conter erros, assim como filhos. Não sou especialista com o componente Symfony Forms , mas na prática você não obterá alguns erros do formulário em si, como erro de proteção CSRF ou erro de campos extras . Eu sugiro remover essa separação.

Usando estrutura de resultado desnormalizada

Alguns autores sugerem colocar todos os erros dentro de um array simples. Assim, todas as mensagens de erro do próprio formulário e de seus filhos serão adicionadas ao mesmo array com diferentes estratégias de indexação: baseadas em números para os próprios erros do tipo e baseadas em nomes para erros filhos. Eu sugiro usar a estrutura de dados normalizada do formulário:

errors:
    - "Self error"
    - "Another self error"

children
    - "some_child":
        errors:
            - "Children error"
            - "Another children error"

        children
            - "deeper_child":
                errors:
                    - "Children error"
                    - "Another children error"

    - "another_child":
        errors:
            - "Children error"
            - "Another children error"

Dessa forma, o resultado pode ser facilmente iterado posteriormente.

Minha solução

Então aqui está minha solução para este problema:

use Symfony\Component\Form\Form;

/**
 * @param Form $form
 * @return array
 */
protected function getFormErrors(Form $form)
{
    $result = [];

    // No need for further processing if form is valid.
    if ($form->isValid()) {
        return $result;
    }

    // Looking for own errors.
    $errors = $form->getErrors();
    if (count($errors)) {
        $result['errors'] = [];
        foreach ($errors as $error) {
            $result['errors'][] = $error->getMessage();
        }
    }

    // Looking for invalid children and collecting errors recursively.
    if ($form->count()) {
        $childErrors = [];
        foreach ($form->all() as $child) {
            if (!$child->isValid()) {
                $childErrors[$child->getName()] = $this->getFormErrors($child);
            }
        }
        if (count($childErrors)) {
            $result['children'] = $childErrors;
        }
    }

    return $result;
}

Espero que ajude alguém.

Slava Fomin II
fonte
@weaverryan você pode dar uma olhada na minha solução, por favor? É válido ou há desvantagens ou equívocos? Obrigado!
Slava Fomin II
1

SYMFONY 3.1

Simplesmente implementei um método estático para lidar com a exibição de erros

static function serializeFormErrors(Form\Form $form)
{
    $errors = array();
    /**
     * @var  $key
     * @var Form\Form $child
     */
    foreach ($form->all() as $key => $child) {
        if (!$child->isValid()) {
            foreach ($child->getErrors() as $error) {
                $errors[$key] = $error->getMessage();
            }
        }
    }

    return $errors;
}

Esperando ajudar

Shigiang Liu
fonte
1

Symfony 3 e mais recente

Recentemente, criei uma função que cria uma árvore de erros de formulário. Isso será útil para retornar a lista de erros ao front-end. Isso se baseia em tipos de formulário com:

'error_bubbling' => false

Código:

public static function getFormErrorsTree(FormInterface $form): array
{
    $errors = [];

    if (count($form->getErrors()) > 0) {
        foreach ($form->getErrors() as $error) {
            $errors[] = $error->getMessage();
        }
    } else {
        foreach ($form->all() as $child) {
            $childTree = self::getFormErrorsTree($child);

            if (count($childTree) > 0) {
                $errors[$child->getName()] = $childTree;
            }
        }
    }

    return $errors;
}

Resultado:

Array
(
    [name] => Array
        (
            [0] => This value is not valid.
        )

    [emails] => Array
        (
            [0] => Array
                (
                    [0] => Given e-mail is not valid.
                    [1] => Given e-mail is not valid #2.
                )
            [1] => Array
                (
                    [0] => Given e-mail is not valid.
                    [1] => Given e-mail is not valid #2.
                )

        )

)

Aviso : eu sei que os erros de campos de nível mais profundo podem ser substituídos se o nível mais alto tiver erros, mas isso é propositalmente para o meu uso.

Krzysztof Trzos
fonte
Perfeito para var_dump, obrigado
ReaperSoon
0

Para Symfony 2.1:

Esta é minha solução final juntando muitas outras soluções:

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;
}
Fernando PG
fonte