Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour, je n'ai pas touvé de solution "propre" à mon problème en cherchant dans les forums donc si quelqu'un a "LA" solution parfaite
Lorsque j'envoi un formulaire à un controller d'action via la methode 'post' je fais ceci :
function addAction() {
$post = $this->_request->getPost();
if($this->db->insert('matable',array(.....)) {
Si l'insertion a marché je redirige comme ceci:
$this->_redirect(/controller/autreaction);
} else {
sinon ....
}
}
problème si l'utilisateur rafraichi sa page, l'insertion se fait plusieurs fois.
J'ai vu plusieurs solutions (au niveau de la base de données uniqid,stocké l'objet en session et testé s'il a déjà été passé,...) tout cela me semble être un peu du bricolage non ?
Comment faites vous avec zend_framework pour éviter cela ?
merci d'avance !
Hors ligne
Quelle est la page que ton utilisateur rafraichit ? La redirection se fait-elle bien ?
Pour ma part quand je veux récupérer un formulaire je mets une condition
$request = $this->getRequest(); if($request->isPost()) { //traitement et enregistrement des donnees; } else{ ..... }
Si ça peut t'aider
Hors ligne
Oui je fais ça aussi mais si l'utilisateur rafraichi la page ça demande s'il veut renvoyer les données du formulaire ...
Hors ligne
Ok j'ai trouvé, il faut faire le traitement dans une autre action car sinon ça demande de recharger.
En gros le formulaire sur l'action indexAction envoi vers traitementAction qui redirige vers indexAction en cas d'ajout réussi
Voilou, si quelqu'un a une solution avec la même action ça peut être intéressant
Dernière modification par MaitreTsiang (18-08-2009 17:39:42)
Hors ligne
C'est la meme solution qu j'utilise (i-e traitement dans une autre action). Ce que je fais c'est que je crée l'objet row avant d'afficher le formulaire, et je le transmet (apres l'avoir serialisé) à l'action de traitement.
Ainsi j'ai
/** * Prepare un enregistrement pour l'afficher dans le formulaire * redirige vers showForm * * Cette redirection permet de ne plus faire de requete si le formulaire * n'est pas validé * * la redirection est effective si $perform est vrai. * Pour surcharger cette méthode tout en gardant sont fonctionnement * appeler la methode parente avec $perform à false * ajouter les traitements desires puis appeler * $this->_redirect($redirect); * * @param boolean $perform * @return null * @see showForm */ public function addAction($perform = true) { $this->session->saveMethod = 'add'; // création de l'objet row $rowObject = $this->model->newRow(); $data = $rowObject->toArray(); // menregistrement de l'objet row en session $this->session->rowObject = serialize($rowObject); // données du formulaire $this->session->formData = $data; // Reconduction des messages $messages = $this->_flashMessenger->getMessages(); foreach ($messages as $message) { $this->_flashMessenger->addMessage($message); } // Message formulaire $this->_flashMessenger->addMessage( $this->_messages['formFieldRequired']); $redirect = $this->_to('process-form'); if ($perform) { $this->_redirect($redirect); } else { return $redirect; } } /** * Recherche l'enregistrement pour l'afficher dans le formulaire * redirige vers showForm * * Cette redirection permet de ne plus faire de requete si le formulaire * n'est pas validé * * la redirection est effective si $perform est vrai. * Pour surcharger cette methode tout en gardant sont fonctionnement * appeler la methode parente avec $perform à false * ajouter les * traitements desires puis appeler * $this->_redirect($redirect); * * @param boolean $perform * @return null * @see showForm */ public function editAction($perform = true) { $this->session->saveMethod = 'edit'; $id = $this->_request->get('id'); // création du row $rowObject = $this->model->fetchRow($id); $data = $rowObject->toArray(); if (!$data) { // Si aucune donnée, rediriger vers la liste $this->_flashMessenger->addMessage( $this->_messages['unknowItem'] . $id); $redirect = $this->_to('show-list'); } else { // enregistrement du row en session $this->session->rowObject = serialize($rowObject); // données du formulaire $this->session->formData = $data; // Message du formulaire $this->_flashMessenger->addMessage( $this->_messages['formFieldRequired']); $redirect = $this->_to('process-form'); } // redirection if ($perform) { $this->_redirect($redirect); } else { return $redirect; } } /** * Affiche le formulaire d'edition d'un element. * * @return null */ public function processFormAction() { if (isset($this->session->rowObject)) { $this->view->headTitle($this->_titles[$this->session->saveMethod], 'PREPEND'); $this->view->crud->cancelAction = 'show-list'; $this->view->crud->cancelButton = $this->_buttons['cancel']; $this->view->crud->saveButton = $this->_buttons['save']; $this->view->formErrors = $this->session->formErrors; // validation et enregistrement du formulaire if ($this->getRequest()->isPost()) { $dataSource = $this->getRequest()->getPost(); // récupération de l'objet row depuis la session $rowObject = unserialize($this->session->rowObject); // passage des valeurs du formulaire au row $rowObject->setFromArray($dataSource); /* * vu que l'objet row a été serialisé, il faut le reconnecter * à la bd * Pour cela on lui donne le nom de sa table */ $rowObject->setTable($this->model->getTable()); // enregistrement try { $pk = $rowObject->save(); $this->session->unsetAll(); $redirect = $this->_to('view'); $this->_redirect($redirect . "/id/$pk"); } catch (Fast_Form_Exception $e) { // formulaire invalide $form = $rowObject->getForm(); // Récupération des messages d'erreur $errors = $form->getMessages(); // messages d'erreur $this->_flashMessenger->addMessage( $this->_messages['invalidFormData']); foreach ($errors as $error) { $error = array("error" => $error[0]); $this->_flashMessenger->addMessage($error); } } catch (Fast_Exception $e) { $this->_flashMessenger->addMessage($this->_messages['unsaved']); // et le formulaire est réaffiché } } else { // Affichage initial du formulaire $rowObject = unserialize($this->session->rowObject); /* * vu que l'objet row a été serialisé, il faut le reconnecter * à la bd * Pour cela on lui donne le nom de sa table. * Ceci permet aussi de récupérer le formulaire */ $rowObject->setTable($this->model->getTable()); $form = $rowObject->getForm(); } // rendu $this->view->form = $form; } else { // si trigger_error('Invalid context to call show-formAction', E_USER_WARNING); $redirect = $this->_to('show-list'); $this->session->unsetAll(); $this->_redirect($redirect); } }
Je mettrai bientot les fichiers complets en ligne.
Dernière modification par lesauf (20-08-2009 22:12:42)
Hors ligne
Salut, personnellement je ne suis pas un fan du zend_form je trouve cela trop lourd et le code généré ne me plait pas donc je reste à la technique 'old school'
Merci pour ta réponse
Hors ligne
bonjour
zf ne le mets pas en œuvre par défaut et les exemples n'en parlent jamais
il existe pourtant un design pattern destiné à ce problème
il s'agit u PRG Post Redirect Get
en clair l'action de ton formulaire en mode post récupère les donnée et le mets en session
puis fait un redirect vers l'action en mode get
si l'utilisateur faut un refresh c'est l'action Get qui est exécuté donc seulement l'affichage du résultat
tu trouvera de la doc sir Wikipédia
et quelques exemples dans ce forum d'utilisation de ce pattern dans ZF
A+JYT
Hors ligne