Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Symfony 2] Éviter le renvoi de données POST

    26 avril 2017 à 21:19:00

    Bonjour à tous,

    J'utilise Symfony 2.8 pour un site internet complet où j'ai pas mal de formulaire.

    Aujourd'hui, je souhaite éviter le renvoi de données POST quand un utilisateur actualise une page ou appuie sur F5 après l'envoie d'un formulaire, qu'il contienne des erreurs ou non. J'ai fait beaucoup de recherche sur ce problème, mais je n'ai rien trouvé pour le régler.

    Habituellement, sur un site PHP sans Framework, je ferais sur toutes mes pages les actions habituelles permettant d'empêcher le renvoi de données POST :

    • Si il y a des données POST, les enregistrer en session et rediriger sur la même page
    • Si il y a des données post en SESSION, les remettre dans la variable $_POST et détruire la variable de session qui contenait le contenu POST

    Mais là en Symfony, je ne vois pas trop comment procéder ? Surtout que je veux que ce soit général pour tous mes formulaires, je ne voudrais pas trop les refaire un par un car j'ai beaucoup de formulaire...

    Voici mon code :

    /**
         * @Route(
    	 *     "/formulaire",
    	 *     name="formulaire"
    	 * )
         */
        public function formulaireAction(Request $request)
        {
    		$form = new Formulaire();
    		$form = $this->createForm(new FormulaireType(), $form);
    		
    		// Si le formulaire a été rempli
    		if ($form_creer_article->handleRequest($request)->isValid()) {
    			
    			$em = $this->getDoctrine()->getManager();
    			$em->persist($article);
    			$em->flush();
    
    			$request->getSession()->getFlashBag()->add('message', 'Formulaire enregistré !');
    					
    			// Une redirection ici empêche le renvoi de données POST seulement quand le formulaire est validé et non quand il contient des erreurs
    			//return $this->redirectToRoute('formulaire');
    		}
    		
            return $this->render('formulaire.html.twig', array('form' => $form->createView()));
        }



    -
    Edité par dada17xs 26 avril 2017 à 21:22:59

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      28 avril 2017 à 1:13:39

      salut,

      coté PHP il n'y a que la redirection qui fonctionnera, je pense qu'il faut regarder du coté de javascript, je n'ai pas fait de recherche mais je suis certain qu'il existe un truc en jquery.

      edit : http://stackoverflow.com/questions/2830542/prevent-double-submission-of-forms-in-jquery

      A+

      -
      Edité par Anonyme 28 avril 2017 à 1:17:57

      • Partager sur Facebook
      • Partager sur Twitter
        4 mai 2017 à 18:22:17

        Je sais bien que cela existe en JQuery, mais je voudrais le faire côté Symfony où je ne trouve aucune solution !

        J'ai essayé de mettre en variable de session la variable Request serializé, redirigé sur la même page, et deserializé la variable de session pour la mettre dans la variable Request, mais si je fais ça, les ->handleForm ne fonctionne plus...

        • Partager sur Facebook
        • Partager sur Twitter
          4 mai 2017 à 18:57:34

          Salut,

          Il y a une bonne pratique Symfony qui consiste a toujours rediriger l'utilisateur après une requete POST pour éviter ce genre de problème. Jquery ou javascript n'est absolument pas la bonne solution, ca a pleins d'inconvénients que je ne prendrais pas le temps d'expliquer là. Pour résoudre ton problème : 

          public function postAction(){
          
          //ta logique métier pour traiter ton form puis 
          
          return $this->redirect($this->get('router')->generate('nom_de_ta_route_vers_ou_rediriger'));
          
          }


          Si tu veux une solution plus intégrée, voici un exemple plus complet.

          • Partager sur Facebook
          • Partager sur Twitter
            5 mai 2017 à 10:05:20

            Cette méthode fonctionne quand le formulaire est validé, mais si le formulaire n'est pas validée et qu'on souhaite afficher une erreur, cela ne fonctionne pas

            Cas où cette solution ne fonctionne pas :

            • Si $form->isValid() renvoi false
            • Si le formulaire n'est pas validé par une quelconque autre condition
            • Partager sur Facebook
            • Partager sur Twitter
              5 mai 2017 à 15:29:40

              J'imagine que tu peux procéder comme ça?

              public function formulaireAction(Request $request)
                  {
                      $form = new Formulaire();
                      $form = $this->createForm(new FormulaireType(), $form);
                       
                      // Si c'est un POST
                      if ($request->isMethod('POST') {
                           //Si le formulaire est correct
                           if ($form_creer_article->handleRequest($request)->isValid()) {
                              $em = $this->getDoctrine()->getManager();
                              $em->persist($article);
                              $em->flush();
               
                              $request->getSession()->getFlashBag()->add('message', 'Formulaire enregistré !');
                          }
                          // Dans tous les cas, que le formulaire soit correct ou non, on redirige
                          return $this->redirectToRoute('ma_route_qui_va_bien');
                      }
                       
                      return $this->render('formulaire.html.twig', array('form' => $form->createView()));
                  }

              Je ne comprend pas trop l’intérêt de faire ça vu que tu perds les messages d'erreur mais bon?

              -
              Edité par Whouki 5 mai 2017 à 15:31:52

              • Partager sur Facebook
              • Partager sur Twitter
                5 mai 2017 à 21:50:21

                Tu ne perds pas les messages d'erreurs car il sont en flash et existeront jusqu'à que tu les affiches une fois.

                Cette méthode n'est pas comme je l'attendais car on doit la refaire sur tous les formulaires mais elle me va. Je voyais peut-être la vie un peu trop en rose car, en PHP sans Framework, sur tous mes sites, ce que je faisais c'est une fonction qui est exécutée à chaque appel de page qui, s'il y a des données POST, les met en session et redirige sur la page actuelle, et si il y a des données post en SESSION, elle les remet dans la variable POST tout bêtement, comme ça on touche à aucun formulaire du site, mais je crois que ce n'est pas possible en Symfony, je vais devoir faire cette méthode sur tous mes formulaires malgré le nombre qu'il y en a x)

                • Partager sur Facebook
                • Partager sur Twitter
                  13 mai 2017 à 23:28:00

                  Je viens de m'apercevoir qu'avec cette méthode, si le formulaire est faux, il ne remet pas les dernières valeurs entrées par défaut, du coup cette méthode ne fonctionne pas
                  • Partager sur Facebook
                  • Partager sur Twitter
                    15 mai 2017 à 9:35:12

                    Eh bien oui, forcément, les dernières informations entrées dans le form sont postées mais pas sauvegardées.

                    Donc elles sont seulement disponibles dans l'action et n'y sont pas sauvegardées.

                    Si tu veux qu'il les garde en mémoire, il faut les sauvegarder en session.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      8 juin 2017 à 11:22:22

                      Et comment faire ça automatiquement sur tous les formulaires sans avoir à les modifier un par un ?

                      -
                      Edité par dada17xs 8 juin 2017 à 12:06:24

                      • Partager sur Facebook
                      • Partager sur Twitter
                        8 juin 2017 à 14:42:16

                        J'imagine que si tu écoutes l'événement "POST_SET_DATA" tu devrais pouvoir t'en sortir?

                        Rien de sur cependant, ça ne me semble pas être un comportement normal et donc, il faut chipoter un peu :/

                        http://symfony.com/doc/current/form/events.html

                        • Partager sur Facebook
                        • Partager sur Twitter
                          8 juin 2017 à 20:39:31

                          Ca ne semble pas être un comportement normal, pourtant c'est ce que fait Openclassroom sur le formulaire de login par exemple.

                          Quand on entre ses pseudo/mot de passe, qu'on valide, qu'on se trompe ou pas, si appuie sur F5, ça ne renvoie pas les données

                          • Partager sur Facebook
                          • Partager sur Twitter
                            9 juin 2017 à 10:59:32

                            Oui, bien sur, si on ne se trompe pas, on rentre dans la condition "Formulaire Valide" et donc, on est redirigés.
                            Et donc pas de problème de sauvegarde en session du formulaire ;)
                            • Partager sur Facebook
                            • Partager sur Twitter

                            [Symfony 2] Éviter le renvoi de données POST

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown