Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Hello tout le monde,
j'ai des petites questions relatifs à Zend_auth, je pense que beaucoup d'entre vous pourrons m'aider. d'avance merci.
#1: la durée de la session affecté à Zend_auth et ouverte tant que le navigateur n'est pas fermé. peut on régler ce paramètre ? peut on détecter le moment ou l'utilisateur ferme son navigateur, afin de réaliser une action dessus ?
#2: je suis un peu perdue avec Zend_Acl et je cherche à réaliser un truc simple. J'ai écrit un adapter pour zend_auth, jusque la pas de problème. J'ai 3 types de compte (1 type non loggé, 1 type membre et 1 type webmaster). Qu'elle serait la meilleure façon de procéder pour définir ces 2 types (je ne tiens pas compte du non loggé) ? Sachant que tous les utilisateurs connectés on accès à toutes les pages mais qu'en fonction de la page on n'affiche pas la même chose. En gros il faut juste que je sache quel type de compte c'est.
voila ))
Hors ligne
#1 Voir la doc de Zend_Session concernant les expiratiosn
#1bis le seul moyen de détecter la fermeture de la page est avec javascript
#2 pour savoir quel type de comptes est un utilisateur, tu as 2 possibilités :
- soit tu utilises les ACL (isAllowed('webmaster', 'page', 'faire ca'))
- soit tu n'utilises pas les acl et tu utilises directement ton model utilisateur pour savoir de quel type est l'utilisateur courant (je ne connais pas ton model, mais par exemple if ($user->type == 'webmaster') ...)
Hors ligne
#1. ok
#2. J'ai crée un adapter pour Zend_auth. Par conséquent j'ai redéfinis la méthode authenticate.
lorsque le user est valide voila mon retour:
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $compte->getLogin(), array());
j'ai essayé de passer un objet mais cela m'a généré une exception:
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $compte, array());
Tu vois un autre moyen, a par bien sur de réinitialiser chaque fois la classe compte avec le login ?
Hors ligne
1. Pour la durée de connexion je procède comme ceci :
$db = self::$registry->database; $auth = Zend_Auth::getInstance(); //-- Récupère l'instance de Zend_Auth //-- Gestion de la déconnexion après un laps de temps donné --// $storage = new Zend_Auth_Storage_Session(self::$TXT_NAME_SESSION); //$sessionNamespace = new Zend_Session_Namespace($storage->getNamespace()); self::$scholastieNamespace->setExpirationSeconds(4200); $auth->setStorage($storage); $authAdapter = new Zend_Auth_Adapter_DbTable($db); //-- Créer une instance Auth_Adaptater de type Table $loginAuth = new LoginAuth($db,$authAdapter,$auth);
J'utilise une session (ici Scholastie, cherche pas pourquoi j'ai appelé ça comme ça, c'est le prénom féminin le plus moche à ma connaissance (et c'est celui de ma copine )). Dans cette session je range mon objet acl qui est initialisé.
2. Par contre là, le mieux c'est de savoir exactement ce qui change et sur quoi vont porter tes acl. Normalement, les acl sont utilisés pour dire si un utilisateur à le droit d'accéder à une ressource (généralement, une page). Mais dans ton cas, si je comprends bien, l'utilisateur peut accéder à toutes les pages, qu'il soit admin ou member. Par conséquent, je n'utiliserai pas les Acl dans ce cas, qui risque de compliquer un truc simple (c'est un avis avec le peu d'information que tu as cité). J'imagine que tu as une table utilisateur et une table role (contenant admin, invité, member...) et à un utilisateur est attribué un role. Si c'est tout ce que tu as, tu peux écrire un plugin qui recherche avant chaque action la page demandé en fonction du role de l'utilisateur et fournir donc le résultat que tu souhaites. Ceci dit, c'est un avis parmi tant d'autre.
Bon courage
Hors ligne
#1. En effet, cette façon de gérer la session n'est pas mal du tout.
#2. Tu as quasiment compris mon pb (c'est vrai j'aurais pu être plus précis). En fait je ne pense pas que le plugin soit adapté dans mon cas. Le type de compte va me permettre sur certaines pages d'afficher tel ou tel information en fonction du type. mais uniquement sur des pages précises. donc pas besoin de redirection.
Le mieux, dans mon cas, serait de pouvoir sauvegarder un objet, dans Zend_auth_result comme expliqué au dessus. Penses tu que c est possible ?
PS: j'espère que t'a copine ne va pas lire le post, sinon gare à la crise de nerfs.
Dernière modification par bucheron (15-07-2008 12:12:28)
Hors ligne
Le plugin ne fait pas de redirection (sauf si tu le lui demande). Ce qui pourrait être intéressant pour toi, c'est de charger le contenu que tu souhaites afficher dans le plugin et le placer dans une variable qui serait défini dans le registry par exemple. T'en penses quoi ?
Hors ligne
je ne pense pas que c est le top.
Car le contenu ce n'est pas une page ou un bout de page, c'est des portions html.
Je m'explique, sur une page on peut afficher à différents endroit des éléments relatifs à un type de compte
donc ce que je souhaitais faire c'était récupérer l'objet en faisant
$compte = $auth->getIdentity();
puis en le manipulant comme un simple objet:
if ($compty->type == TypeCompte::Webmaster )...
je viens de penser à un truc.
En fait si le passage par objet n'est pas possible un des moyens serait d'enregistrer une nouvelle variable session lors du login.
je vais essayer. Mais si tu as d'autres propositions je suis preneur
Hors ligne
En fait si le passage par objet n'est pas possible
Tu veux dire quoi par là ? N'oublie pas que tu peux sérialiser un objet (donc sauvegarder son état => valeurs des membres), même le stocker dans une base de données, et le passer ou tu veux (ce qui n'est pas forcément conseillé). Ceci dit, je te proposai la solution de chargé le contenu dans un plugin si tu chargeais le contenu de la page... Si je comprends bien, il s'agit plus de modules que tu souhaites afficher (menu supplémentaires par exemple...). Dans ce cas, il est vrai qu'il existe de nombreuses solutions correctes pour répondre à ton problème, dont les sessions en font parties (quoi qu'il en soit, je pense que tu as au moins une session) mais maintenant il faut que tu sois sûr de ce que tu vas mettre dans cette session.
En ce qui me concerne, dés qu'il s'agit d'une manipulation de données de la sorte (par exemple pour mes menus en fonction du type d'utilisateur connecté) j'ai toujours 2 classes : une classes qui ne gère que les requêtes SQL et dans aucun cas ne contient des fonctions d'affichages. La deuxième classe, comme tu t'en doutes ne contient à sont tour que les opérations d'affichages, de récéptions des paramètres et utilise la première classe. Encore une fois, c'est une solution parmi tant d'autre.
Bon courage
Hors ligne
Peux tu me donner un exemple de comment sérialiser un objet ?
voila ce que j'ai essayé :
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, serialize($compte ) array());
et voila le mess d'erreur qu'il me retourne:
You cannot serialize or unserialize PDO instances
Hors ligne
Perso je ne sérialize pas mes models car, si entre temps, un admin modifie le compte, j'ai besoin de le savoir. Donc, je conserve que l'id de la personne te un plugin fait le select pour s'assurer de l'état du compte tout le temps.
A toi de savoir si il est nécessaire de sérializer ou non ton objet.
Une fois que tu as récuperer ton objet, en effet, il est très facile de faire
if ($compty->type == TypeCompte::Webmaster )
Hors ligne
En effet, je comprend ton point de vue.
Mais si je décide quand même de sérialiser l'objet, comment faire ??
Hors ligne
Comme disais Norky, je ne serialise pas d'objet contenant un objet BD. Si tu tiens à le faire, regarde dans la section Zend_Db de la doc et tu trouveras le moyen de sauver une db. Par contre si tu veux sauvegarder un objet quelconque, ce sont les fonctions php qui répondent à ce besoin : $temp = serialize($objet) et $objet = unserialize($temp).
En fait, une session ne fait que de la serialisation...
Hors ligne
Je n'utilise pas Zend_Db, mais si elle implemente __serialize et __unserialize, normalement, pas besoin d'appeler les fonctions serialize et unserialize, car le fait de mettre un object en session provoque forcément la serialisation de l'objet je crois (et donc appelle la fonction __serialize)
Il faut faire des tests..
Hors ligne
ok je vais essayer qq tests et je posterais les résultats
merci
Hors ligne
Hello,
Apparemment non, bien que Zend_Db implémente serialize et unserialize lorsque je sérialise un objet contenant une Zend_Table par exemple, j'ai une exception qui n'empêche pas le bon fonctionnement de mon appli mais qui est affiché en bas de page. Par conséquent, mes tests n'ont pas été concluant.
Hors ligne
Dans ce cas, il faut appelé toi même serialize :
$s = new Zend_Session_Namespace('userProfileNamespace');
$s->user = serialize($user); // la, __serialize sera appelé
puis pour récuperer :
$s = new Zend_Session_Namespace('userProfileNamespace');
$user = unserialize($user); // la, __unserialize sera appelé
Hors ligne
Bonjour,
J'ai le même problème ...
Je galère sur ce problème depuis ce matin et j'en vois pas le bout.
Je suis bien content de trouver un post qui en parle.
J'essaye de stocker dans la session un objet de type Zend_Db_Select :
// select sur un vue d'une table dans MySQL ... $select = $this->_db->select() ->from($this->_name);
J'ai tester avec et sans serialize ...
1) Si j'exécute ce code :
// session par défaut créée dans le bootstrap $session = Zend_Registry::get('session'); try { $session->select = $select; } catch ( Exception $e ) { die($e->getMessage()); } // affichage du "select" qui est supposé être dans la session die($session->select);
je me prend ça dans les dents à l'exécution :
// affichage comme il faut du select ... Fatal error: Exception thrown without a stack frame in Unknown on line 0
Ensuite, sous IE 6, le reste de l'application tourne normalement. Par contre, sous Firefox 2, rien ne va plus, toute l'appli est plantée en donnant ça (quelque soit le code que je fais tourné ... le bootstrap qui utiliser l'auth qui fait planter) :
Fatal error: Uncaught exception 'PDOException' with message 'You cannot serialize or unserialize PDO instances' in D:\wamp\www\site\web\library\Zend\Session.php:404 Stack trace: #0 [internal function]: PDO->__wakeup() #1 D:\wamp\www\site\web\library\Zend\Session.php(404): session_start() #2 D:\wamp\www\site\web\library\Zend\Session\Namespace.php(116): Zend_Session::start(true) #3 D:\wamp\www\site\web\library\Zend\Auth\Storage\Session.php(87): Zend_Session_Namespace->__construct('auth') #4 D:\wamp\www\site\web\index.php(136): Zend_Auth_Storage_Session->__construct('auth') #5 {main} thrown in D:\wamp\www\site\web\library\Zend\Session.php on line 404 Fatal error: Exception thrown without a stack frame in Unknown on line 0
La ligne 404 de session.php correspond à "session_start()" ... surement une blague des développeurs de mettre un si importante fonction sur la ligne 404 !!!
Bref, Le seul moyen de pouvoir de nouveau utiliser FF2 est de le fermer et de le rouvrir ...
2) Si j'exécute ce code :
// session par défaut créée dans le bootstrap $session = Zend_Registry::get('session'); try { $session->select = serialize($select); } catch ( Exception $e ) { die($e->getMessage()); } // echo du "select" qui est supposé être dans la session die($session->select);
je me prend ça dans les dents :
You cannot serialize or unserialize PDO instances // pas de select ... il passe pas par le "die($session->select)" // => normal il a exécuté le catch ...
Je suis dans la mouise ... je pourrais toujours stocker dans la session mon select sous forme de String, mais que je le récupèrerai, je perdrai les avantages que me procure l'objet Zend_Db_Select ( ajout de where, order, etc ... )
Donc s'il y a une solution efficace qui marche, je suis preneur
Merci d'avance.
Hors ligne