Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
J'essaye de connecter une base de données MYSQL avec ZF2 mais sans grand succès. Pourtant je me suis inspiré du projet quickstart ZF2.
Donc dans mon module.config.php j'ai ceci :
<?php return array( 'bootstrap_class' => 'webservicepush\Bootstrap', 'layout' => 'layouts/layout.phtml', 'di' => array( 'instance' => array( 'alias' => array( 'index' => 'webservicepush\Controller\IndexController', 'test' => 'webservicepush\Controller\TestController', 'error' => 'webservicepush\Controller\ErrorController', 'view' => 'Zend\View\PhpRenderer', ), 'webservicepush\Model\DbTable\Utilisateur' => array('parameters' => array( 'config' => 'Zend\Db\Adapter\Pdo\Mysql', )), 'Zend\Db\Adapter\Pdo\Mysql' => array('parameters' => array( 'config' => array('dbname' => 'geotchat', 'host' => 'localhost', 'username' => 'root', 'password' => '*****' ) )), 'Zend\View\HelperLoader' => array( 'parameters' => array( 'map' => array( 'url' => 'webservicepush\View\Helper\Url', ), ), ), 'Zend\View\HelperBroker' => array( 'parameters' => array( 'loader' => 'Zend\View\HelperLoader', ), ), 'Zend\View\PhpRenderer' => array( 'parameters' => array( 'resolver' => 'Zend\View\TemplatePathStack', 'options' => array( 'script_paths' => array( 'application' => __DIR__ . '/../views', ), ), 'broker' => 'Zend\View\HelperBroker', ), ), ), ), 'routes' => array( 'default' => array( 'type' => 'Zend\Mvc\Router\Http\Regex', 'options' => array( 'regex' => '/(?P<controller>[^/]+)(/(?P<action>[^/]+)?)?', 'spec' => '/%controller%/%action%', 'defaults' => array( 'controller' => 'error', 'action' => 'index', ), ), ), 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'index', 'action' => 'index', ), ), ), ), );
Je passe à Zend\Db\Adapter\Pdo\Mysql mes différentes informations mais sans succès.
Dans ma classe Utilisateur qui étend AbstractTable j'ai ceci :
<?php namespace webservicepush\Model\DbTable; use Zend\Db\Table\AbstractTable; class Utilisateur extends AbstractTable { protected $_name = 'UTILISATEUR'; public function getMembreAll() { return $this->fetchAll()->toArray(); } }
Et dans mon controller j'essaye de faire ceci :
public function indexAction() { $table = new Utilisateur(); return array( 'title' => 'WEBSERVICE PUSH' ); }
Et il me dit ceci :
Message: No adapter found for webservicepush\Model\DbTable\Utilisateur
Alors personnellement, je ne comprend pas comment en donnant juste les infos dans module.config.php il arrive à s'en sortir. Besoin d'une petite explication.
Merci d'avance
Hors ligne
En gros, l'injecteur de dépendance va, comme son nom l'indique, "injecter" des objets dans d'autres objets. Ainsi, dans ton module.config.php, tu indiques que ton objet "webservicepush\Model\DbTable\Utilisateur" doit être initialisé avec une instance d'un objet 'Zend\Db\Adapter\Pdo\Mysql' appelé 'config'.
Puis la ligne suivante, tu indiques les paramètres avec lesquels doit être créer l'objet 'Zend\Db\Adapter\Pdo\Mysql'. Ca, c'est ce que tu indiques avec ton injecteur de dépendance.
Sauf que dans ton code, tu fais un simple $table = new Utilisateur(). Evidemment, c'est pas magique. Il peut pas deviner, juste en instanciant un objet.
Ce qu'il faut donc faire, c'est récupérer ton injecteur de dépendance, et explicitement lui demander que tu veux créer une instance de type "webservicepush\Model\DbTable\Utilisateur". A partir de là, ton injecteur de dépendance SAIT qu'il faut lui passer un objet de type 'Zend\Db\Adapter\Pdo\Mysql'.
Ce qu'il faut faire, c'est, dans ton contrôleur, plutôt que de créer ton objet ainsi :
$table = new Utilisateur();
Il faut faire :
$table = $this->getLocator('di')->get('webservicepush\Model\DbTable\Utilisateur');
Ecrire webservicepush\Model\DbTable\Utilisateur étant un peu long, tu peux ajouter un nouvel alias dans le module.config.php :
'alias' => array( 'index' => 'webservicepush\Controller\IndexController', 'test' => 'webservicepush\Controller\TestController', 'error' => 'webservicepush\Controller\ErrorController', 'view' => 'Zend\View\PhpRenderer', 'model-utilisateur' => 'webservicepush\Model\DbTable\Utilisateur' ),
Ce qui permet de ramener ton code à :
$table = $this->getLocator('di')->get('model-utilisateur');
A noter : Je ne sais pas trop comment fonctionne la classe DbTable (j'utilise Doctrine), mais pour que l'injecteur de dépendance fonctionne, il faut que la classe de base (à savoir Zend\Db\Table\AbstractTable) ait bien un membre nommé 'config'.
Si ce n'est pas le cas, il faut que tu penses à ajouter cette variable membre ainsi que la fonction setConfig, afin que l'injecteur de dépendance puisse correctement l'initialiser.
Hors ligne
D'accord merci bakura pour ces petites explications. C'est pas vraiment évident aux premiers abords
Tu pourrais rentrer plus en détail sur la partie DbTable quand même ? Car pour le moment ce que j'ai essayé ne fonctionne pas. Comment je peux vérifier les classes qui sont loader automatiquement sur ma page ?
Dans ma config je pense avoir bien fait non ? Et pourtant il me dit ceci maintenant :
Message: No entry is registered for key 'Zend\Db\Adapter\Pdo\Mysql'
C'est beau de faire joujou avec ZF2 mais c'est pas évident sans bonne docs
Merci d'avance de ton aide
PS : Je regarde dans les sources de Zend je ne trouve pas de fichier Zend\Db\Adapter\Pdo\Mysql
Il y a que Mssql.php, Oci.php, Pgsql.php et Sqlite.php ... Étrange non ?
Dernière modification par akrogames (26-11-2011 15:19:44)
Hors ligne
Désolé, je n'utilise pas DbTable donc je ne pourrai pas t'aider davantage.
Je viens de regarder les sources et apparemment (c'est assez bizarre, je comprends pas la raison), l'adapter pour MySQL est : Zend/Db/Adapter/PdoMysql et non Zend/Db/Adapter/Pdo/Mysql
Donc tu as déjà un truc à changer ^^.
Au niveau de ton initialisation dans le module.config.php, ça m'a l'air correct autrement...
C'est beau de faire joujou avec ZF2 mais c'est pas évident sans bonne docs
C'est clair. Mieux vaut que tu apprennes à lire toi même le code source de certaines parties du code ...
Hors ligne
Super cela fonctionne avec Zend\Db\Adapter\PdoMysql !
Dorénavant on doit faire appel au DI pour appeler nos classes alors ?
Merci a toi bakura
Hors ligne
Cool !
Non, il ne faut pas tout le temps faire appel au Di, mais juste quand c'est nécessaire. Je pense que j'essayerai d'écrire un petit tuto sur comment ça fonctionne. Il y a bien de la doc' mais elle est peut-être un peu trop abstraite...
Mais concrètement, si tu veux créer un objet d'un certain type, s'il n'a aucune dépendance avec d'autres classes, ce n'est pas la peine d'utiliser le Di.
Hors ligne
bakura a écrit:
En gros, l'injecteur de dépendance va, comme son nom l'indique, "injecter" des objets dans d'autres objets. Ainsi, dans ton module.config.php, tu indiques que ton objet "webservicepush\Model\DbTable\Utilisateur" doit être initialisé avec une instance d'un objet 'Zend\Db\Adapter\Pdo\Mysql' appelé 'config'.
Puis la ligne suivante, tu indiques les paramètres avec lesquels doit être créer l'objet 'Zend\Db\Adapter\Pdo\Mysql'. Ca, c'est ce que tu indiques avec ton injecteur de dépendance.
Sauf que dans ton code, tu fais un simple $table = new Utilisateur(). Evidemment, c'est pas magique. Il peut pas deviner, juste en instanciant un objet.
Ce qu'il faut donc faire, c'est récupérer ton injecteur de dépendance, et explicitement lui demander que tu veux créer une instance de type "webservicepush\Model\DbTable\Utilisateur". A partir de là, ton injecteur de dépendance SAIT qu'il faut lui passer un objet de type 'Zend\Db\Adapter\Pdo\Mysql'.
Ce qu'il faut faire, c'est, dans ton contrôleur, plutôt que de créer ton objet ainsi :
$table = new Utilisateur();
Il faut faire :
$table = $this->getLocator('di')->get('webservicepush\Model\DbTable\Utilisateur');
Ecrire webservicepush\Model\DbTable\Utilisateur étant un peu long, tu peux ajouter un nouvel alias dans le module.config.php :Code:
'alias' => array( 'index' => 'webservicepush\Controller\IndexController', 'test' => 'webservicepush\Controller\TestController', 'error' => 'webservicepush\Controller\ErrorController', 'view' => 'Zend\View\PhpRenderer', 'model-utilisateur' => 'webservicepush\Model\DbTable\Utilisateur' ),Ce qui permet de ramener ton code à :
$table = $this->getLocator('di')->get('model-utilisateur');
A noter : Je ne sais pas trop comment fonctionne la classe DbTable (j'utilise Doctrine), mais pour que l'injecteur de dépendance fonctionne, il faut que la classe de base (à savoir Zend\Db\Table\AbstractTable) ait bien un membre nommé 'config'.
Si ce n'est pas le cas, il faut que tu penses à ajouter cette variable membre ainsi que la fonction setConfig, afin que l'injecteur de dépendance puisse correctement l'initialiser.
J'ai plusieurs remarques:
1 - Doctrine2 fait aussi de l'injection de dépendance on dirait:
$candidatAdresseRepository = $this->getEntityManager()->getRepository('Entity\TCandidatAdresse');
2 - Ce système est très problématique dans un IDE comme Zend Studio car on n'a pas la compétion de code et il ne peut donc pas détecter si la classe existe ou pas.
Enfin quel est l'intérêt de cet injecteur de dépendance?
Avoir a disposition l'objet 'locator' dans chaque classe (métier ou composant) ?
De plus lorsque j'essaie de remplacer tous mes appels a mes classes metiers:
$candidatService = new \Candidat\Model\Service\CandidatService($this->getEntityManager());
par :
$candidatService = $this->getLocator('di')->get('\Candidat\Model\Service\CandidatService,$this->getEntityManager());
Message: Invalid instantiator
\Zend\Di\Di.php(120): Zend\Di\Di->newInstance('Doctrine\ORM\En...', Array)
En effet j'instancie toutes mes classes de services avec :
public function __construct(EntityManager $em) {
$this->_em = $em;
}
Donc je ne sais pas trop comment passer des paramètres au constructeur de ma classe de service.
Y'a une doc ici http://packages.zendframework.com/docs/ … nager.html
mais ca n'a pas l'air de fonctionner chez moi
Dernière modification par booradley (27-11-2011 16:14:05)
Hors ligne
Un lien intéressant : http://www.slideshare.net/fabpot/depend … endcon2010
Les diapos 77 a 80 disent que un DI container ne gère pas tous les objets mais seulement ceux de type "Global" comme les connexions à la base de données. Donc a apriori on ne doit pas l'utiliser pour les classes métier.
Enfin, c'est ce que je comprends....
Dernière modification par booradley (27-11-2011 18:42:52)
Hors ligne
Rien ne t'empêche de l'utiliser pour les classes métiers. Typiquement, tu peux vouloir injecter un "salt" pour hasher tes mots de passe dans le modèle "Utilisateur".
Hors ligne
Hello, je remonte ce fil de discussion car je me pose une question au sujet de la connexion vers une base de données. En effet il est dit dans le tutorial d'akrabat et dans ce sujet, qu'il est nécessaire de préciser à l'injecteur l'objet Zend\Db\Adapter\Mysqli pour instancier un objet DbTable.
Ma question est la suivante, est-il possible d'avoir une connexion générique à affecter à tous nos objets d'un seul coup sans avoir à redéfinir un attribut 'config' pour chacun d'eux ou est-on obligé de le préciser ? Peux on gérer une connexion pour toute l'application ou doit on la gérer par module ?
Hors ligne