risposta-alla-domanda-sullo-sviluppo-web-bd.com

Symfony2 form non valido senza errori

Ho un problema con un modulo CRUD generato da Symfony2 . (Con documenti MongoDB, ma non penso che questo sia collegato)

Nel metodo createAction () del mio controller, quando eseguo il debug del risultato del modulo:

$form->isValid() // returns false

$form->getErrors() // returns en empty array(0) {}

Quindi, non ottengo nulla usando form_errors(form) sul mio template di ramoscello (che sembra normale a causa di $form->getErrors() return vuoto)

E i valori scritti non vengono sostituiti nella forma ...

Qualcuno ha un'idea?

57

La prima cosa da capire è che la convalida viene eseguita sul modello, non sulla forma. Il modulo può contenere errori, ma solo se ha un campo mappato alla proprietà che non convalida. Quindi se il tuo modulo non contiene il campo non valido (magari un'asserzione NotNull su una proprietà che non è nel modulo), non mostrerà l'errore.

La seconda cosa è che $form->getErrors() mostrerà solo errori per quel livello, ogni form figlio può contenere i propri errori. Quindi, se si desidera verificare gli errori, è necessario scorrere i campi e chiamare getErrors su ciascun campo. Il metodo getErrors sulla classe Form può essere ingannevole in questo modo.

60
Peter Kruithof

Per eseguire il debug di un modulo, utilizzare $form->getErrorsAsString() anziché $form->getErrors()

$form->getErrorsAsString() dovrebbe essere usato solo per eseguire il debug del modulo ... conterrà gli errori di ogni elemento figlio che non è il caso di $form->getErrors()

Come menziona Peter, $form->getErrors() non restituirà la somma di tutti gli errori dei moduli figli. 

Per capire come un form può essere non valido e avere un getErrors () che restituisce un array vuoto, puoi dare un'occhiata al metodo isValid () della classe form di symfony. Come puoi vedere, ci sono 2 casi in cui il modulo non è valido, il primo test per il modulo generale e il secondo caso per ciascun elemento figlio.

public function isValid()
{
    //...

    //CASE I : IF CHILD ELEMENTS HAVE ERRORS, $this->errors WILL CONTAIN
    //THE ERROR ON THE CHILD ELEMENT AND NOT ON THE GENERAL 'errors' FIELD 
    //ITSELF

    if (count($this->errors) > 0) {
        return false;
    }

    //CASE II: AND THIS IS WHY WE ARE TESTING THE CHILD ELEMENTS AS WELL
    //TO CHECK WHETHER THERE ARE VALID OR NOT

    if (!$this->isDisabled()) {
        foreach ($this->children as $child) {
            if (!$child->isValid()) {
                return false;
            }
        }
    }

    return true;
}

Pertanto ogni bambino del modulo può contenere un errore, ma $form->getErrors() stesso non restituirà tutti gli errori. Considerando un modulo con molti elementi figlio, generalmente $ form-> getErrors () con un errore CSRF se il CSRF non è corretto.

61
Mick

Aggiornamento per Symfony 2.6

Quindi, a seconda della versione di Symfony2:

symfony2.3

die($form->getErrorsAsString());

A partire da symfony2.5 , la funzione getErrorsAsString() è deprecata (verrà rimossa in Symfony3) e dovresti utilizzare il seguente metodo:

die((string) $form->getErrors());     // Main errors
die((string) $form->getErrors(true)); // Main and child errors

Da symfony2.6 , puoi anche usare la funzione dump (dev environment) se hai attivato DebugBundle:

dump((string) $form->getErrors());     // Main errors
dump((string) $form->getErrors(true)); // Main and child errors
49
COil

Ho appena avuto lo stesso problema. Per me, il modulo non era valido, ma non sono riuscito a ottenere alcun errore utilizzando $form->getErrors() o $form->getErrorsAsString(). In seguito ho scoperto che ho dimenticato di passare il token CSRF al modulo in modo che non venga inviato e $form->handleRequest($request) non ha fatto nulla (nessuna convalida). Come ho visto la risposta di @ pit, ho provato a usare

$form->submit($request);

$form->getErrorsAsString();

ha restituito un errore:

ERRORE: il token CSRF non è valido. Si prega di provare a inviare nuovamente il modulo.

Ecco alcune spiegazioni nella documentazione di Symfony2: http://symfony.com/doc/current/book/forms.html#handling-form-submissions

18
micmia

Per Symfony (> = 3.2 - 4), puoi usare:

foreach($form->getErrors(true, false) as $er) {
    print_r($er->__toString());
}

per vedere gli errori, ovviamente.

4
Somen Diégo

Da Symfony 3 in poi, come da documentazione, dovresti usare la nuova implementazione:

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

Ciò restituirà tutti gli errori come una stringa. 

3
Adam

Per me il modulo non è stato inviato, anche se avevo un pulsante di invio . Ho aggiunto il codice per risolvere il problema

$request = $this->get('request');
if($request->isMethod("POST")){
      $form->submit($request);
        if($form->isValid()){
        // now true
        }
}
3
pit

Sì È corretto, cosa dice Peter Kruithof In SF 2.8 questa è la mia funzione, per ottenere gli errori dei campi 

 private function getErrorsForm(\Symfony\Component\Form\Form $form)
{
    $response =  array();

    foreach ($form as $child) {
         foreach ($child->getErrors(true) as $error) {
            $response[$child->getName()][] = $error->getMessage();
         }
    }

    return $response;
}
2
ederrafo

Se invii i dati tramite AJAX , potresti aver dimenticato di includere il nome del modulo sulle chiavi dei tuoi dati e quindi di essere "vittima" di ...

# line 100 of Symfony/Component/Form/Extension/HttpFoundation/HttpFoundationRequestHandler.php 
// Don't submit the form if it is not present in the request

Il che significa che, durante il tentativo di gestire la richiesta, il meccanismo di elaborazione delle richieste non ha trovato il nome del modulo all'interno dei dati GET/POST (che indica come un array).

Quando si esegue il rendering di un modulo nel modo consueto, ciascuno dei suoi campi contiene il nome del modulo come prefisso nell'attributo nome my_form[child_field_name].

Quando usi ajax, aggiungi il nome del tuo modulo come prefisso nei dati!

data : {
    "my_form" : {
       "field_one" : "field_one_value"
       ...
    }
}
2
Stphane

Mi sono imbattuto in questo errore e ho scoperto che mi stavo dimenticando di "gestire" la richiesta. Assicurati di averlo intorno ...

public function editAction(Request $request)
{
    $form = $this->createForm(new CustomType(),$dataObject);
    /**  This next line is the one I'm talking about... */
    $form->handleRequest($request);
    if ($request->getMethod() == "POST") {
        if ($form->isValid()) {
        ...
1
Layton Everson

Sembra che tu abbia un problema di validazione. Il modulo non è valido per l'invio. Presumo che tu stia usando Annotazioni per la tua convalida. Assicurati di avere questo in cima all'entità.

use Symfony\Component\Validator\Constraints as Assert;

e anche questo sopra ogni proprietà

/**      
 * @Assert\NotBlank()      
 */

NotBlank() può essere modificato in qualsiasi vincolo per soddisfare le tue esigenze.

Maggiori informazioni sulla convalida possono essere trovate su: http://symfony.com/doc/current/book/validation.html

Ulteriori informazioni sui vincoli Assert sono disponibili all'indirizzo: http://symfony.com/doc/current/book/validation.html#constraints

0
Dave Mascia