Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
Dans l'optique d'avoir une session active ( que le membre ne se log qu'une fois de temps en temps, les cookies se chargeant de le reco ), je n'arrive pas à contacter ma BDD parce que getServiceLocator retourne tout le temps null. Je précise que j'execute cette méthode depuis mon module.php
#ConnexionController.php de mon module
public function recuperationUtilisateurAction(){ $session = new \Zend\Session\Container('session'); if(empty($session->firstTime)){ if(! empty($_COOKIE['cookie-autoconnexion'])){ $id_user = $this->getUserTable()->reconnecterDepuisToken($_COOKIE['cookie-autoconnexion']); # et je le reconnecte ... } $session->firstTime="Testé"; } } public function getUserTable() { if (!$this->userTable) { $sm = $this->getServiceLocator(); $this->userTable = $sm->get('user-table'); #Ca plante ici, en tentant de faire le get } return $this->userTable; }
#Module.php
public function onBootstrap($e) { $a = new \MonSite\Controller\ConnexionController(); $a->recuperationUtilisateurAction(); }
Que dois je faire ?
Merci
Hors ligne
Salut. Pour te répondre : PAS DU TOUT COMME CA .
C'est normalement que getServiceLocator() renvoie null puisque tu ne l'affectes pas. Normalement les contrôleurs sont instanciés par le service manager qui lui passe la référence au service locator du coup quand tu utilises normalement ton contrôleur le service locator ne renvoie pas null.
Dans ton cas il y a une solution simple et rapide pour régler le problème, tu la trouveras surement par toi même et je ne vais pas te la donner car c'est totalement contraire à l'utilisation du ZF2 de faire comme tu fais. Un contrôleur sert uniquement à faire des traitements liés à ta vue c'est à dire récupérer les données pour les transmettre à la vue et valider les formulaires c'est tout !!
Ta fonction recuperationUtilisateurAction() déjà dans ton cas d'utilisation ne nécessite pas du postfix Action puisqu'il n'est pas appelé par le mécanisme de routing. Bref c'est pas bon.
Ce que je te conseil donc c'est de passer par une couche service à laquelle tu donneras la référence au service manager qui fera les traitements que tu fais. De ce fait ton contrôleur n'est pas pollué par de la merde (parlons franchement). Pour que ton service ai une référence au service manager j'ai déjà répondu à la question plusieurs fois. Tu as une interface à implémenter et tu dois récupérer ton service depuis le service manager.
Le raisonnement est plutôt bon je pense. Je le ferais aussi dans le Bootstrap par contre pas via un contrôleur mais via un service pour que ça soit plus propre.
Hors ligne
C'est vrai que cela peut faire bizarre de voir le code ci dessus, mais ma quête est depuis trop longtemps de choper un endroit ou il y aurait le service manager. J'ai donc dérivé, et j'ai finis par avoir une methode recuperationUtilisateurAction alors que je sais bien qu'il n'a rien à faire la et qu'elle n'a pas à s'appeller "Action". Je comprends amplement ce que tu dis ... !
Pour ta solution à l'arrache, je vois meme pas ta solution magique : je te rappelle que Zend 2 sans tutoriel, pour 1er framework de sa vie, c'est ingobable.
Et je vais regarder avec les pistes que tu m'as laissé si je peux trouver une façon plus digne ... !
Hors ligne
serutan a écrit:
Pour ta solution à l'arrache, je vois meme pas ta solution magique : je te rappelle que Zend 2 sans tutoriel, pour 1er framework de sa vie, c'est ingobable.
Sisi c'est jouable, c'est mon premier framework php donc je sais de quoi je parle. Faut du temps . Pour ma solution à l'arrache je te l'ai donné en partie après c'est à toi de l'adapter manuellement. Si je te le disais tu dirais "ah oui"
Et je vais regarder avec les pistes que tu m'as laissé si je peux trouver une façon plus digne ... !
Regardes les sujets qui en causent sur ce forum tu as normalement toutes les réponses
Hors ligne
Beh ca marche.
# Le nouveau onBootstrap, j'ai beaucoup galéré pour trouver ou on recuperait le service manager... public function onBootstrap($e) { $app = $e->getParam('application'); $simpleClass = $app->getServiceManager()->get('autoconnexion'); }
#Ajout dans getServiceConfig d'une factorie qui fait le job: 'auto-connexion' => function($sm) { $reco = new reconnexionAutomatique(); $reco->setSM($sm->get('user-table')); $reco->testConnexion(); return $reco; }
# Et le corps de ma classe public function setSM($sm){ $this->sm = $sm; } public function getUserTable() { return $this->sm; } recuperationUtilisateurAction(){...}
Hors ligne
Si ça marche tant mieux mais il y a beaucoup plus simple. Tu as juste à avoir une classe reconnexionAutomatique qui implémente une certaines interface ça doit être de tête ServiceManagerAwareInterface ou un truc du genre. Ensuite tu fais comme t'as fait dans le getServiceConfig sauf que tu n'as plus besoin de faire de factorie tu peux le faire directement en faisant :
'auto-connexion' => 'Namespace\reconnexionAutomatique'
Et dans le onBootstrap tu fais comme tu as fait, ça va autmatiquement instancier reconnexionAutomatique et y injecter le service manager grace à cette fameuse interface.
Par ailleurs les fonctions annonyme pour les factories c'est pas recommandé. Il vaut mieux faire une classe reconnexionAutomatiqueFactory que tu déportes et dans le getServiceConfig tu fais :
'auto-connexion' => 'Namespace\reconnexionAutomatiqueFactory'. Dans ton cas tu n'en auras pas besoin de toute façon.
Hors ligne
Orkin a écrit:
Si ça marche tant mieux mais il y a beaucoup plus simple. Tu as juste à avoir une classe reconnexionAutomatique qui implémente une certaines interface ça doit être de tête ServiceManagerAwareInterface ou un truc du genre.
C'est déjà ce que je fais ( je pense ):
Dis en pensant, vu que j'apprends lentement mais surement le framework, es ce que mon organisation est cohérente ? J'ai vu des dossiers en plus dans le module, à quoi servent ils ? ( Tant qu'a partir sur des bonnes bases, autant que ce soit tôt ) ( ormis le fait qu'il n'y ai pas l'implementation de module qui séparerait le code, mea culpa )
Sinon je pense avoir saisie ce que tu dis, merci beaucoup ... !
Hors ligne
serutan a écrit:
C'est déjà ce que je fais ( je pense )
Non puisque tu a un setter dans ta classe reconnexionAutomatique qui se nomme setSM et celui présent dans l'interface est setServiceLocator. Donc si tu l'avais implémenté tu auras ce setter. De plus lorsque l'on implémente cette interface il est inutile de donner la référence au service manager via une factory ou une fonction anonyme comme tu l'as fait c'est le service manager qui s'en charge de lui même.
Lis la doc sur le service manager tu pourras corriger tes erreurs .
Pour le reste je te répondrais demain si je n'oublie pas.
Hors ligne