Symfony2 : 요청을 양식에 바인딩 한 후 양식 유효성 검사 오류를 얻는 방법


110

다음은 내 saveAction코드입니다 (양식이 데이터를 전달하는 위치).

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

내 질문은 : $form->isValid()반환 하면 오류를 어떻게 얻 false습니까?

답변:


117

두 가지 가능한 방법이 있습니다.

  • 오류 발생시 사용자를 리디렉션하지 않고 {{ form_errors(form) }}템플릿 파일 내에 표시
  • 액세스 오류 배열 $form->getErrors()

22
두 번째로 제안했지만 form-> getErrors ()는 빈 배열을 반환합니다.
putolaruan 2011-08-08

2
또한 첫 번째 작업 (php 템플릿 <? php echo $ view [ 'form']-> errors ($ form)?>)을 수행했지만 여전히 비어 있습니다!
putolaruan 2011-08-08

59
@mives error_bubbling각 필드에 대한 옵션을 명시 적으로 설정하여 양식 유형에서 true로 설정해야 합니다.
kgilden 2011 년

5
사용자 정의 유효성 검사기를 사용하는 경우 Symfony는 $ form-> getErrors ()에서 해당 유효성 검사기에 의해 생성 된 오류를 반환하지 않습니다.
Jay Sheth 2014 년

13
당신은 또한 할 수 $form->getErrors(true)뿐만 아니라 자식 폼의 오류를 포함하는
크리스

103

Symfony 2.3 / 2.4 :

이 함수는 모든 오류를 가져옵니다. "CSRF 토큰이 유효하지 않습니다. 양식을 다시 제출하십시오."와 같은 양식에있는 것입니다. 또한 오류 버블 링이없는 양식 하위에 대한 추가 오류도 있습니다.

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

모든 오류를 문자열로 가져 오려면 :

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

Symfony 2.5 / 3.0 :

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

문서 :
https://github.com/symfony/symfony/blob/master/UPGRADE-2.5.md#form https://github.com/symfony/symfony/blob/master/UPGRADE-3.0.md#form (at 바닥 : The method Form::getErrorsAsString() was removed)


1
이것은 현재 Symfony 2.4에서 가장 정답 인 것 같습니다.
Slava Fomin II

@Flip it 완벽하게 2.5에서 작동
iarroyo 2014-08-29

1
훌륭한 대답이지만 Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller 구성 요소 에서 getErrorMessages 가 누락 되었으므로$errors[$child->getName()] = $this->getErrorMessages($child); 예외가 발생했습니다 . 그래서 나는 그것을$form_errors[$child->getName()] = $child->getErrorsAsString();
Ahad Ali

3
@AhadAli는 재귀 함수이므로이 기능이 필요한 클래스에 코드 스 니펫을 넣으면 자신을 호출 할 수 있습니다. "수정"은 중첩 된 양식에 도달하지 못하게합니다. 37 명의 다른 사람들에게도 효과
Flip

@Flip 아 죄송합니다, 나는 단지보고 있었고 $this->getErrorMessages()컨트롤러와 Symfony API의 일부 내부에서 직접 호출되었다고 생각했습니다.
Ahad Ali

47

아래는 나를 위해 일한 솔루션입니다. 이 함수는 컨트롤러에 있으며 모든 오류 메시지와이를 발생시킨 필드의 구조화 된 배열을 반환합니다.

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 이상 :

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

5
gist.github.com/2011671을 개선 했지만 여전히 내가 원하는 것은 아닙니다. 배열 키를 필드 이름으로 만들고 싶지만 그렇지 않습니다.
umpirsky

9
@SalmanPK Twig는 위 코드의 어느 곳에서도 참조되지 않습니다. 나는 당신의 의견을 이해하지 못한다고 생각합니다.
Icode4food

1
이전 요점에 대한 수정 사항은 Symfony 2.1.7에서 작동합니다. gist.github.com/WishCow/5101428
K. Norbert

오타가있는 것 같습니다 $this->getFormErrors해야 $this->getErrorMessagesSymfony2.1에서 샘플에

@umpirsky 필드 이름을 얻으려면 다음을 얻었습니다. $ child-> getConfig ()-> getOptions () [ 'label'] 영원히 알아 내야했습니다 ...
jsgoupil 2013

35

유효성 검사기를 사용하여 특정 엔터티에 대한 오류를 가져옵니다.

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 참조 :


감사합니다. 필요한 것 +1
Phill Pafford

4
각 엔터티를 개별적으로 검증하는 것이 좋은 방법인지 잘 모르겠습니다. 복잡한 계층 구조가 있다면 어떨까요? 두 번째 문제는 유효성 검사가 두 번 발생한다는 것입니다.
Slava Fomin II

3
@SlavaFominII- "두 번째 문제는 유효성 검사가 두 번 발생한다는 것입니다."-좋은 지적, 아무것도 새로 고쳐지지 않습니다! 이후 동일한 오류 목록!
BentCoder

20

현재 SF 2.6.3을 사용하는 적절한 (번역 가능한) 메시지를 얻으려면 여기에 마지막 기능이 있습니다 (위의 어느 것도 더 이상 작동하지 않는 것 같습니다).

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

Form :: getErrors () 메서드는 이제 두 번째 인수 ($ flatten)를 true로 전환하지 않는 한 FormErrorIterator 의 인스턴스를 반환 합니다 . (그런 다음 FormError 인스턴스 를 반환 하고 current () 메서드없이 getMessage () 메서드를 직접 호출해야합니다.

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

)

가장 중요한 것은 실제로 오류를 얻기 위해 첫 번째 인수를 true로 설정하는 것입니다. 두 번째 인수 ($ flatten)를 기본값 ( true ) 으로두면 FormError 인스턴스가 반환 되고 false로 설정되면 FormErrorIterator 인스턴스 가 반환 됩니다.


같은 것을 사용하는 것이 좋습니다.
손상 유기

그렇지 않습니까? :) @KidBinary
Cedo

절대적으로 화려한, 친구
손상 유기

더 나은 옵션은 다음과 같습니다. $ errors = array_map (function ($ item) {return $ item-> current ()-> getMessage ();}, $ campaignForm-> getErrors (true, false));
엔리케 Quero

Symfony 2.7에 적합한 솔루션
Yann Chabot

16

내 플래시 메시지에 만족했습니다. $form->getErrorsAsString()

편집 (Benji_X80에서) : SF3 용 $form->getErrors(true, false);


3
나는 그것이 오래된 대답이라는 것을 알고 있지만 향후 참조를 위해 : This method should only be used to help debug a form.( 출처 )
cheesemacfly

getErrorsAsString ()은 3.0에서 더 이상 사용되지 않습니다. 다음을 사용하십시오. $ form-> getErrors (true, false);
Benji_X80

15

더 이상 사용되지 않는 기능이없는 심포니 2.1 이상을위한 기능 :

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

나는이 게시물에 대한 새로운 답변을 게시하려고했지만 당신은 나를 펀치로 이겼다. 메서드 호출을 찾을 수없는 이유를 파악하기 위해 소스 코드를 살펴 봐야했습니다.
Dr. Knowitall

나는 이것이 오류 버블 링이 true로 설정된 항목에서 오류를 가져 오지 않는 것으로 나타났습니다. SF2.4
kinghfb 2014

@stwe 첫 번째 IF진술 의 목적은 무엇 입니까? 상호 배타적 인 이유는 무엇입니까? 내가 볼 수있는 한 : 양식은 자식뿐만 아니라 자체 오류를 가질 수 있습니다.
Slava Fomin II

4

번역 된 양식 오류 메시지 (Symfony2.1)

이 정보를 찾기 위해 많은 노력을 기울 였으므로 양식 오류 번역에 대한 메모를 추가 할 가치가 있다고 생각합니다.

@Icode4food답변은 양식의 모든 오류를 반환합니다. 그러나 반환되는 배열은 메시지 복수화 또는 번역 을 고려하지 않습니다 .

@Icode4food콤보를 갖도록 foreach 응답 루프를 수정할 수 있습니다 .

  • 특정 양식의 모든 오류 가져 오기
  • 번역 된 오류 반환
  • 필요한 경우 복수화 고려

여기있어:

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

이 답변은 3 개의 다른 게시물에서 모아졌습니다.


방금 귀하의 버전을 시도하고 갔다 Fatal Error: Call to undefined method Symfony\Component\Form\FormError::getMessagePluralization(). 나는 이것이 Symfony 2.1에만 해당한다고 생각합니까?
Czar Pino 2013

4

SYMFONY 3.X

여기에 제공된 다른 SF 3.X 메서드는 빈 데이터를 양식에 제출할 수 있기 때문에 작동하지 않았습니다 (하지만 NotNull / NotBlanck 제약 조건이 있음). 이 경우 오류 문자열은 다음과 같습니다.

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

그다지 유용하지 않습니다. 그래서 이것을 만들었습니다.

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

반환 할 것 :

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

3

유효성 검사기 서비스를 사용하여 제약 조건 위반을 가져올 수도 있습니다.

$errors = $this->get('validator')->validate($user);

6
이것은 개체를 확인하지만 양식은 확인하지 않습니다. 예를 들어 CRSF 토큰이 오류의 원인 인 경우 메시지가 포함되지 않습니다.
Icode4food 2011

3

번역 된 양식 오류 메시지 (Symfony2.3)

내 버전의 문제 해결 :

/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);

Symfony 2.5에서는 모든 필드 오류를 매우 쉽게 얻을 수 있습니다.

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

3

대한 심포니 3.2 및 사용이 위

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

각 오류 설명 텍스트에서 성가신 ' Error : '텍스트를 제거 하려면 str_replace를 사용하십시오 .

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

2

사용자 지정 유효성 검사기를 사용하는 경우 Symfony는 $form->getErrors().$form->getErrorsAsString()필요한 모든 오류를 반환하지만 출력은 불행히도 배열이 아닌 문자열로 형식이 지정됩니다.

오류가 발생한 위치에 관계없이 모든 오류를 가져 오는 데 사용하는 방법은 사용중인 Symfony 버전에 따라 다릅니다.

대부분의 제안 된 솔루션에는 모든 하위 양식을 스캔하고 관련 오류를 하나의 배열로 추출하는 재귀 함수를 만드는 것이 포함됩니다. Symfony 2.3에는 $form->hasChildren()기능이 없지만 $form->all().

다음은 Symfony 2.3 용 도우미 클래스로, 모든 형식에서 모든 오류를 추출하는 데 사용할 수 있습니다. (Yapro가 Symfony의 github 계정에있는 관련 버그 티켓에 대한 주석의 코드를 기반으로합니다.)

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

전화 코드 :

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

}

2

@Jay Seth의 답변에 따라 특히 Ajax Forms에 대한 FormErrors 클래스 버전을 만들었습니다.

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

사용 (예 : 행동) :

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

Symfony 버전 : 2.8.4

JSON 응답의 예 :

{
    "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"
    }]
}

오류 개체에는 입력 DOM 요소의 ID 인 "키"필드가 포함되어 있으므로 오류 메시지를 쉽게 채울 수 있습니다.

부모 안에 자식 양식이있는 cascade_validation경우 부모 양식의 setDefaults.


1

Twig 오류 표시와 함께 사용하기 위해 Symfony 2.1 이상에서는 단순히 검색하는 대신 FormError를 추가하도록 함수를 변경했습니다. 이렇게하면 오류를 더 잘 제어 할 수 있고 각 개별 입력에 error_bubbling을 사용할 필요가 없습니다. 아래 방식으로 설정하지 않으면 {{form_errors (form)}}가 공백으로 유지됩니다.

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

}

1

$ form-> getErrors ()는 나를 위해 작동합니다.


1

이 솔루션을 생각해 냈습니다. 최신 Symfony 2.4에서 견고하게 작동합니다. .

나는 몇 가지 설명을하려고 노력할 것이다.

별도의 유효성 검사기 사용

다른 작성자가 제안한 것처럼 엔티티를 검증하고 제약 위반 메시지를 반환하기 위해 별도의 유효성 검사를 사용하는 것은 나쁜 생각이라고 생각합니다.

  1. 모든 엔티티를 수동으로 검증하고 검증 그룹을 지정하는 등의 작업이 필요합니다. 복잡한 계층 적 형식의 경우 실용적이지 않으며 신속하게 처리 할 수 ​​없습니다.

  2. 이렇게하면 양식을 한 번은 양식으로, 한 번은 별도의 유효성 검사기로 두 번 검증 할 수 있습니다. 이것은 성능 측면에서 나쁜 생각입니다.

오류 메시지를 수집하기 위해 자식과 함께 양식 유형을 반복적으로 반복하는 것이 좋습니다.

독점 IF 문과 함께 몇 가지 제안 된 방법 사용

다른 저자가 제안한 일부 답변에는 다음과 같이 상호 배타적 인 IF 문이 포함되어 있습니다. if ($form->count() > 0)또는 if ($form->hasChildren()).

내가 볼 수있는 한 모든 양식에는 자식뿐만 아니라 오류도있을 수 있습니다. 저는 Symfony Forms 구성 요소에 대한 전문가는 아니지만 실제로 CSRF 보호 오류 또는 추가 필드 와 같은 양식 자체의 일부 오류를 얻지 못할 것입니다. 오류 입니다. 이 분리를 제거하는 것이 좋습니다.

비정규 화 된 결과 구조 사용

일부 저자는 모든 오류를 일반 배열 안에 넣을 것을 제안합니다. 따라서 양식 자체와 하위 항목의 모든 오류 메시지는 다른 인덱싱 전략을 사용하여 동일한 배열에 추가됩니다. 유형 자체 오류의 경우 숫자 기반, 하위 오류의 경우 이름 기반입니다. 다음 형식의 정규화 된 데이터 구조를 사용하는 것이 좋습니다.

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"

이렇게하면 나중에 결과를 쉽게 반복 할 수 있습니다.

내 솔루션

이 문제에 대한 해결책은 다음과 같습니다.

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

누군가를 도울 수 있기를 바랍니다.


@weaverryan 제 솔루션을 살펴볼 수 있습니까? 유효합니까, 아니면 결점이나 오해가 있습니까? 감사합니다!
Slava Fomin II

1

심포니 3.1

단순히 오류 표시를 처리하는 정적 메서드를 구현했습니다.

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

도움을 희망


1

Symfony 3 이상

최근에 폼 오류 트리를 만드는 함수를 만들었습니다. 이는 오류 목록을 프런트 엔드로 되 돌리는 데 유용합니다. 이는 다음을 갖는 양식 유형을 기반으로합니다.

'error_bubbling' => false

암호:

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

산출:

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

        )

)

주의 사항 : 상위 레벨에 오류가있을 경우 하위 레벨 필드의 오류를 덮어 쓸 수 있다는 것을 알고 있지만 이는 제 용도를위한 것입니다.


var_dump에 적합합니다. 감사합니다
ReaperSoon

0

Symfony 2.1의 경우 :

이것은 다른 많은 솔루션을 결합하는 최종 솔루션입니다.

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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.