Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour à toutes et à tous,
Débutant dans l'utilisation du ZF, je viens solliciter votre aide pour un problème de session.
Architecture de l'application :
Conception MVC modulaire avec un front controleur et plusieurs sous-controleurs d'action (Zend_Controller)
Le front controller se charge entre autre de vérifier les permissions de l'utilisateur à l'aide d'un plugin.
Ce plugin agit au moment du preDispatch() afin de déterminer si l'utilisateur est authentifié et si l'action demandée est autorisée :
Extrait de code du plugin d'authentification et ACL
public function preDispatch(Zend_Controller_Request_Abstract $request){ .... $auth = Zend_Auth::getInstance(); if (!$auth->hasIdentity()) { // si non-authentifié, redirection vers l'action login du sous-controleur auth }else{ // si authentifié, vérification des ACL } ... }
Voici un extrait de code pour l'action login du sous-controleur auth
Extrait de code /auth/login
function loginAction(){ .... $authAdapter->setIdentity($username); $authAdapter->setCredential($password); $auth = Zend_Auth::getInstance(); $result = $auth->authenticate($authAdapter); ... }
Voilà pour ce qui est de l'authentification.
Jusque là, aucun problème, c'est par la suite que ça se complique :
Afin de permettre la saisie sur plusieurs formulaires, j'ai besoin d'enregistrer l'objet qui me sert de modèle dans la session.
Par exemple pour l'ajout d'un contact (un de mes modèles métier), j'utilise l'action 'add' (formulaire + vérif des champs) puis l'action 'confirm' (récap + confirmation de l'enregistrement) du controleur 'ContactController'.
Entre ces 2 actions, l'objet doit être enregistré dans la session.
Extrait de code /contact/add
function addAction(){ // Vérification des champs du contact // si OK, enregistrement dans l'objet contact .... // Enregistrement de l'objet contact dans la session $contactSpace = new Zend_Session_Namespace('contactController'); $contactSpace->objContact = $objContact; // Redirection vers l'action confirm $this->_forward('confirm'); }
Extrait de code /contact/confirm
function confirmAction(){ ... // Récupération de l'objet contact dans la session $contactSpace = new Zend_Session_Namespace('contactController'); $objContact = $contactSpace->objContact; // Enregistrement de l'objet dans la base de données $objContact->save(); ... }
Mon problème :
Lors de l'étape de confirmation d'enregistrement d'un contact, j'obtiens le message d'erreur suivant :
The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition 'Contact' of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in ...
Diagnostic :
Mon problème provient du mécanisme des sessions et plus particulièrement de la nécessité de charger la classe avant d'utiliser session_start() (que je n'utilise pas directement mais qui doit être manipulé par Zend_Auth dans mon plugin Auth/ACL)
Afin de confirmer cette hypothèse, j'ai chargé ma classe Contact dans le front controller avant l'enregistrement de mon plugin et là, plus de pb, tout fonctionne correctement.
Ma question :
Comment faire pour pouvoir enregistrer des objets dans la session conjointement à l'utilisation de Zend_Auth ? (en évitant la solution du chargement des modèles dans le front controller)
J'espère vous avoir exposé clairement mon problème et vous remercie d'avance pour les réponses qu'il vous sera possible de m'apporter.
Dernière modification par Amael (09-04-2008 14:26:00)
Hors ligne
Bonjour Amael,
Dans mes codes je charge l'ensemble des classes qui peuvent se retrouver en session dès le début du index.php.
C'est ni très fin, ni très élégant, mais comme beaucoup d'élément dans une application peuvent initialiser la session, je pense que c'est une solutions plus robuste...
Sinon tu peux aussi utiliser l'autoload.
Ca ne répond pas directement à ta question, mais de façon détournée, ça résoud ton problème...
A+, Philippe
Hors ligne
Merci Philippe pour la rapidité de ta réponse.
Ton post répond bien à ma question et je pense que je vais effectivement m'orienter vers la solution de chargement de l'ensemble des classes dès le début du front controller.
Remarque :
Du fait de mon manque d'expérience avec ZF, je ne savais pas comment résoudre le problème. Je ne savais pas si c'était un problème de conception, si je manquais d'informations sur des éléments du framework ou s'il existait de "bonnes pratiques" afin de résoudre ce pb.
Je suis vraiment rassuré.
Merci encore.
@+
Amaël
Hors ligne
Il me semble que PHP à besoin que le script se finisse pour pouvoir enregistrer quoi que ce soit en session. Je vois que dans ta fonction "addAction" tu fais un "_forward" qui ne termine pas ton script. Peut être pourrais tu essayer avec un "_redirect" ?
Hors ligne
Je confirme : PHP enregistre la session après sa fin, il faut donc rediriger ( ce qui provoque l'établissement d'une nouvelle transaction HTTP) ( ou manipuler session_write_close() ).
Aussi, il faut systématiquement inclure ses classes avant de désérialiser les objets de la session, sinon ce seront des objets incomplete_class
Hors ligne
Merci pour vos recommandations.
Pour récapituler, voici les modifications effectuées afin de solutionner le problème :
- Modification du _forward en _redirect dans l'action 'add' du sous-controleur 'contact' (pour redirection vers action 'confirm')
- Chargement des classes modèles dès le début du front controller
@+
Amaël
Hors ligne
Bonjour,
Je reviens sur ce pb récurrent lorsqu'on utilise des sessions.
La méthode indiquée me semble aussi la meilleure (j'évite aussi le autoload, trop gourmand).
Pb : j'ai une méthode dans ma classe abstraite héritant de Controller_Action tout le boulot de sauvegarde et de restore en session pour les actions filles : aussi, dans cette méthode, je ne connais pas les types d'objets serializées par les actions!
A part utiliser la fonction autoload ou inclure de manière bourrine toutes les classes susceptibles d'être utilisées dans les classes actions filles, je ne vois pas comment faire...sachant la dernière solution n'est pas très maintenable (en effet, quid des nouvelles actions filles?retoucher encore le code de la classe abstraite?).
Probablement que qqun a eu le mm pb?
Yoong
PS : le dernier site sur lequel j'ai développé : http://www.energeo.fr/
Hors ligne
Pages: 1