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
मैंने आपके द्वारा सुझाई गई दूसरी बात की, लेकिन फॉर्म-> getErrors () एक खाली सरणी लौटाता हूं।
पुश्तैनी

2
मैंने पहला भी किया था (w / php टेम्प्लेट <; php इको $ व्यू ['फॉर्म'] -> एरर्स ($ फॉर्म)?>) लेकिन फिर भी यह खाली है!
पुटोलरुआन

59
@mives आपको error_bubblingप्रत्येक और हर क्षेत्र के लिए विकल्प को स्पष्ट रूप से सेट करके अपने फ़ॉर्म प्रकार में सही होना चाहिए ।
किगिल्डेन 14

5
यदि आप कस्टम सत्यापनकर्ताओं का उपयोग कर रहे हैं, तो सिम्फनी उन सत्यापनकर्ताओं द्वारा $ $-> getErrors () में उत्पन्न त्रुटियों को वापस नहीं करता है।
जे शेथ

13
आप $form->getErrors(true)बाल रूपों की त्रुटियों को भी शामिल कर सकते हैं
क्रिस

103

सिम्फनी 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);

सिम्फनी 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 (पर) नीचे: The method Form::getErrorsAsString() was removed)


1
यह वर्तमान सिम्फनी 2.4 के लिए सबसे सही उत्तर की तरह दिखता है।
स्लाव फोमिन II

@ यह पूरी तरह से 2.5
iarroyo

1
ग्रेट उत्तर BUT $errors[$child->getName()] = $this->getErrorMessages($child);अपवाद को फेंक रहा था, क्योंकि GetErrorMessages Symfony \ बंडल \ FrameworkBundle \ नियंत्रक \ नियंत्रक घटक से गायब था । इसलिए मैंने इसे बदल दिया$form_errors[$child->getName()] = $child->getErrorsAsString();
अहद अली

3
@ अहदली यह एक पुनरावर्ती कार्य है, इसलिए जब आप कोड स्निपेट को उस कक्षा में रखते हैं जहाँ आपको इस कार्यक्षमता की आवश्यकता होती है तो यह स्वयं को कॉल करने में सक्षम होगा। आपका "फिक्स" आपको नेस्टेड रूपों तक पहुंचने से रोक देगा। इसने 37 अन्य लोगों के लिए काम किया, यह आपके लिए भी काम करना चाहिए;)
पलटें

@ फीलिंग अरी सॉरी मेरी बुर, मैं केवल देख रहा था $this->getErrorMessages()और मुझे लगा कि इसका कॉल सीधे एक कंट्रोलर के अंदर और सिम्फनी आपी के हिस्से में आएगा ।
अहद अली

47

नीचे समाधान है कि मेरे लिए काम किया है। यह फ़ंक्शन कंट्रोलर में है और सभी एरर मैसेज और उनके कारण होने वाले फ़ील्ड का एक संरचित एरे लौटाएगा।

सिम्फनी 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;
}

सिम्फनी 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 टहनी उपरोक्त कोड में कहीं भी संदर्भित नहीं है। मुझे विश्वास नहीं होता कि मैं आपकी टिप्पणी को समझ पा रहा हूं।
13

1
यहां पिछले गिस्ट के लिए एक फिक्स है, यह सिम्फनी 2.1.7 के तहत काम करता है। gist.github.com/WishCow/5101428
। नॉर्बर्ट

ऐसा लगता है कि एक टाइपो है आपके नमूना में सिम्फनी 2 में $this->getFormErrorsहोना चाहिए$this->getErrorMessages
मिक

@umpirsky फ़ील्ड नाम पाने के लिए, मुझे यह मिला: $ बच्चा-> getConfig () -> getOptions () ['लेबल'] मुझे हमेशा के लिए पता लगाने के लिए ले गया ...
jsgoupil

35

किसी विशिष्ट इकाई के लिए त्रुटियों को प्राप्त करने के लिए Validator का उपयोग करें

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

एपीआई संदर्भ:


धन्यवाद, जो मुझे +1 की जरूरत थी
Phill Pafford

4
मुझे यकीन नहीं है कि यह प्रत्येक इकाई को अलग से मान्य करने के लिए एक अच्छा तरीका है। यदि आपके पास जटिल पदानुक्रमित रूप है तो क्या होगा? दूसरी समस्या यह है कि सत्यापन दो बार होता है।
स्लाव फोमिन II

3
@SlavaFominII - "दूसरी समस्या यह है कि सत्यापन दो बार होता है" - अच्छा बिंदु, कुछ भी ताज़ा नहीं होता है! उसी के बाद त्रुटि सूची!
बेंटकोडर

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

फॉर्म के रूप में :: getErrors () विधि अब FormErrorIterator का एक उदाहरण देता है , जब तक कि आप दूसरे तर्क ($ सपाट ) को सही नहीं करते । (यह तब एक फॉर्मर उदाहरण लौटाएगा , और आपको वर्तमान () विधि के बिना सीधे गेटमेसेज () विधि को कॉल करना होगा:

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

)

वास्तव में सबसे महत्वपूर्ण बात यह है कि त्रुटियों को प्राप्त करने के लिए पहले तर्क को सच करना है। दूसरे तर्क ($ सपाट ) को उसके डिफ़ॉल्ट मान ( सत्य ) पर छोड़ते हुए, फॉर्मराइटर इंस्टेंसेस को वापस करेगा, जबकि यह फॉर्मरिटेटर इंस्टेंसेस को तब लौटाएगा जब वह गलत पर सेट हो।


एक ही सामान का उपयोग कर अच्छा लगा।
ऑर्गेनिक

है ना? :) @KidBinary
Cedo

पूरी तरह से भव्य, दोस्त
:)

बेहतर विकल्प है: $ त्रुटियाँ = array_map (फ़ंक्शन ($ आइटम) {वापसी $ आइटम-> वर्तमान () -> getMessage ();}; $ अभियान) -> getErrors (सच्चा, गलत));
एनरिक कुरो

सिम्फनी 2.7 के लिए अच्छा समाधान
यान चाबोट

16

अपने फ्लैश संदेशों के लिए मैं खुश था $form->getErrorsAsString()

संपादित करें (Benji_X80 से): SF3 उपयोग के लिए $form->getErrors(true, false);


3
मुझे पता है कि यह एक पुराना उत्तर है, लेकिन भविष्य के संदर्भ के लिए: This method should only be used to help debug a form.( स्रोत )
चीज़सेकफ़ेल

getErrorsAsString () 3.0 में पदावनत है, उपयोग: $ फॉर्म-> getErrors (सच्चा, गलत);
बेन्जी_एक्स 12०

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

मैं इस पोस्ट का एक नया उत्तर पोस्ट करने जा रहा था, लेकिन आप मुझे पंच मार रहे थे। मुझे यह पता लगाने के लिए स्रोत कोड के माध्यम से देखना था कि विधि कॉल क्यों नहीं मिली।
डॉ। क्वॉलिटॉल

मैंने देखा है कि यह उन आइटमों से त्रुटियों को नहीं खींचता है जिनमें त्रुटि बुदबुदाती है कि यह सच है SF2.4
राजाफब

@ पहले IFबयान का उद्देश्य क्या है ? यह पारस्परिक रूप से अनन्य क्यों है? जहाँ तक मैं देख सकता हूँ: प्रपत्र में स्वयं त्रुटियों के साथ-साथ बच्चे भी हो सकते हैं।
स्लाव फोमिन II

4

अनुवादित प्रपत्र त्रुटि संदेश (Symfony2.1)

मैं इस जानकारी को खोजने के लिए बहुत संघर्ष कर रहा हूं, इसलिए मुझे लगता है कि यह निश्चित रूप से फॉर्म त्रुटियों के अनुवाद पर एक नोट जोड़ने के लायक है।

@Icode4foodउत्तर फॉर्म की सभी त्रुटियों को लौटा देगा। हालाँकि, लौटाया गया सरणी या तो संदेश बहुवचन या अनुवाद को ध्यान में नहीं रखता है ।

आप @Icode4foodकॉम्बो के लिए उत्तर के फ़ॉरच लूप को संशोधित कर सकते हैं :

  • किसी विशेष फॉर्म की सभी त्रुटियां प्राप्त करें
  • अनुवादित त्रुटि लौटाएं
  • यदि आवश्यक हो तो बहुवचन को ध्यान में रखें

यह रहा:

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()। मुझे शक है कि यह सिम्फनी 2.1 के लिए ही है?
Czar Pino

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 टोकन त्रुटि का कारण था जिसमें संदेश शामिल नहीं होगा।
आईसीोडेफूड

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

सिम्फनी 2.5 में आप सभी फ़ील्ड त्रुटियों को बहुत आसान कर सकते हैं:

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

3

के लिए Symfony 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;
}

यदि आप प्रत्येक त्रुटि वर्णन पाठ में ' त्रुटि: ' पाठ से छुटकारा पाना चाहते हैं, तो str_replace का उपयोग करें ।

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

2

यदि आप कस्टम सत्यापनकर्ताओं का उपयोग कर रहे हैं, तो सिम्फनी उन सत्यापनकर्ताओं द्वारा उत्पन्न त्रुटियों को वापस नहीं करता है $form->getErrors()$form->getErrorsAsString()आपके द्वारा आवश्यक सभी त्रुटियों को वापस कर देगा, लेकिन इसका उत्पादन दुर्भाग्य से एक स्ट्रिंग के रूप में स्वरूपित किया गया है, न कि एक सरणी के रूप में।

जिस विधि का उपयोग आप सभी त्रुटियों को प्राप्त करने के लिए करते हैं (चाहे वे कहां से आए हों), इस बात पर निर्भर करता है कि आप किस सिम्फनी का उपयोग कर रहे हैं।

सुझाए गए अधिकांश समाधानों में एक पुनरावर्ती फ़ंक्शन बनाना शामिल है जो सभी बच्चे रूपों को स्कैन करता है, और संबंधित त्रुटियों को एक सरणी में निकालता है। सिम्फनी 2.3 में $form->hasChildren()फ़ंक्शन नहीं है , लेकिन यह है $form->all()

यहाँ Symfony 2.3 के लिए एक सहायक वर्ग है, जिसका उपयोग आप किसी भी रूप से सभी त्रुटियों को निकालने के लिए कर सकते हैं। (यह सिम्फनी के जीथब खाते में संबंधित बग टिकट पर यापारो की एक टिप्पणी के कोड पर आधारित है।)

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

@ जय सेठ के जवाब के आधार पर, मैंने विशेष रूप से अजाक्स फॉर्म के लिए फॉर्मरर्स क्लास का एक संस्करण बनाया:

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

सिम्फनी संस्करण: 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 तत्व की आईडी है, जिससे आप आसानी से त्रुटि संदेशों को आबाद कर सकते हैं।

यदि आपके पास माता-पिता के अंदर बच्चे के रूप हैं, तो cascade_validationमाता-पिता के फॉर्म के अंदर विकल्प जोड़ना न भूलें setDefaults


1

सिम्फनी 2.1 के लिए ट्विग एरर डिस्प्ले के साथ उपयोग करने के लिए मैंने फंक्शन को बदलने के बजाय उन्हें केवल पुनः प्राप्त करने के लिए एक फॉर्मर को जोड़ने के लिए बदल दिया, इस तरह से आप त्रुटियों पर अधिक नियंत्रण रखते हैं और प्रत्येक व्यक्तिगत इनपुट पर error_bubbling का उपयोग नहीं करना पड़ता है। यदि आप इसे {{form_errors (फॉर्म)}}) से नीचे तरीके से सेट नहीं करते हैं, तो खाली रहेगा:

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

$ फॉर्म-> getErrors () मेरे लिए काम करता है।


1

मैं इस समाधान के साथ आया था। यह नवीनतम सिम्फनी 2.4 के साथ ठोस काम करता है ।

मैं कुछ स्पष्टीकरण देने की कोशिश करूंगा।

अलग सत्यापनकर्ता का उपयोग करना

मुझे लगता है कि संस्थाओं को मान्य करने और अन्य लेखकों द्वारा सुझाए गए उल्लंघन संदेशों को वापस करने के लिए अलग-अलग सत्यापन का उपयोग करना एक बुरा विचार है।

  1. आपको सभी संस्थाओं को मैन्युअल रूप से मान्य करना होगा, सत्यापन समूहों को निर्दिष्ट करना होगा, आदि, जटिल पदानुक्रमित रूपों के साथ यह बिल्कुल व्यावहारिक नहीं है और जल्दी से हाथों से निकल जाएगा।

  2. इस तरह से आप फॉर्म को दो बार मान्य करेंगे: एक बार फॉर्म के साथ और एक बार अलग-अलग वैलिडेटर के साथ। यह प्रदर्शन के दृष्टिकोण से एक बुरा विचार है।

मेरा सुझाव है कि त्रुटि संदेश एकत्र करने के लिए बच्चों के साथ पुनरावर्ती रूप टाइप करें।

अनन्य IF कथन के साथ कुछ सुझाई गई विधियों का उपयोग करना

अन्य लेखकों द्वारा सुझाए गए कुछ उत्तरों में पारस्परिक रूप से अनन्य IF कथन होते हैं: if ($form->count() > 0)या if ($form->hasChildren())

जहाँ तक मैं देख सकता हूँ, हर रूप में त्रुटियों के साथ-साथ बच्चे भी हो सकते हैं। मैं सिम्फनी फॉर्म घटक के साथ विशेषज्ञ नहीं हूं , लेकिन व्यवहार में आपको फॉर्म की कुछ त्रुटियां नहीं मिलेंगी, जैसे सीएसआरएफ सुरक्षा त्रुटि या अतिरिक्त फ़ील्ड त्रुटि। मैं इस अलगाव को दूर करने का सुझाव देता हूं।

निरूपित परिणाम संरचना का उपयोग करना

कुछ लेखक एक सादे सरणी के अंदर सभी त्रुटियों को रखने का सुझाव देते हैं। इसलिए फॉर्म के सभी त्रुटि संदेश स्वयं और इसके बच्चों को अलग-अलग अनुक्रमण रणनीतियों के साथ एक ही सरणी में जोड़ा जाएगा: प्रकार की स्वयं की त्रुटियों के लिए नंबर-आधारित और बच्चों की त्रुटियों के लिए नाम-आधारित। मैं फॉर्म के सामान्यीकृत डेटा संरचना का उपयोग करने का सुझाव देता हूं:

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

मुझे उम्मीद है कि यह किसी की मदद करेगा।


क्या आप मेरे समाधान पर एक नज़र डाल सकते हैं? क्या यह वैध है, या कोई कमियां हैं या कोई गलतफहमी है? धन्यवाद!
स्लाव फोमिन II

1

SYMFONY 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

सिम्फनी 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.
                )

        )

)

सूचना : मुझे पता है कि यदि उच्च स्तर की त्रुटियां हैं, तो गहरे स्तर के फ़ील्ड से त्रुटियों को अधिलेखित किया जा सकता है, लेकिन यह मेरे उपयोग के उद्देश्य से है।



0

सिम्फनी 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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.