Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 26-11-2011 13:20:50

akrogames
Membre
Date d'inscription: 22-03-2010
Messages: 27

Connecter une base de données avec ZF2

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 :

Code:

<?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 :

Code:

<?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 :

Code:

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 wink

Hors ligne

 

#2 26-11-2011 14:56:14

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Connecter une base de données avec ZF2

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.

Hors ligne

 

#3 26-11-2011 15:14:27

akrogames
Membre
Date d'inscription: 22-03-2010
Messages: 27

Re: Connecter une base de données avec ZF2

D'accord merci bakura pour ces petites explications. C'est pas vraiment évident aux premiers abords wink

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 wink

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

 

#4 26-11-2011 16:12:15

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Connecter une base de données avec ZF2

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 yikes...

Hors ligne

 

#5 26-11-2011 17:06:03

akrogames
Membre
Date d'inscription: 22-03-2010
Messages: 27

Re: Connecter une base de données avec ZF2

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

 

#6 26-11-2011 23:08:36

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Connecter une base de données avec ZF2

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

 

#7 27-11-2011 15:38:33

booradley
Membre
Date d'inscription: 10-01-2009
Messages: 163

Re: Connecter une base de données avec ZF2

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

 

#8 27-11-2011 18:34:15

booradley
Membre
Date d'inscription: 10-01-2009
Messages: 163

Re: Connecter une base de données avec ZF2

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

 

#9 27-11-2011 22:08:36

bakura
Administrateur
Date d'inscription: 30-01-2010
Messages: 353

Re: Connecter une base de données avec ZF2

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

 

#10 19-01-2012 09:15:08

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Connecter une base de données avec ZF2

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

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages