Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 26-05-2014 19:52:18

kouamepaul1
Nouveau membre
Date d'inscription: 26-05-2014
Messages: 3

Probleme avec le service manager

Salut a tous,

J'ai besoin d'utiliser le service manager pour accéder a des services a partir des modeles de table. Il y a une methode qui est tres repandu sur le net y compris le manuel de ZF2 mais bizzarement la methode ne marche pas.

Pour etre plus concret, j'ai un mode ArticleTable et un deuxieme modele CategoriesTable. A partir de ArticleTable, je veut acceder a CategoriesTable pour exploiter certaines de ses methodes.

Sur le net, la methode qui est preconisee est la suivante:
1) Referencer CategoriesTable dans Module.php ou dans Module.config.php. Pour mon cas, j'ai utiliser le referencement dans le fichier Module.php. En voici le code:
--------Extrait du Code Module.php -------------
public function getServiceConfig() {
        return array(
            // Le service CategoriesTable
                'Site\Model\CategoriesTable' =>  function($sm) {
                    $tableGateway = $sm->get('CategoriesTableGateway');
                    $table = new Model\CategoriesTable($tableGateway);
                    return $table;
                },
                'CategoriesTableGateway'=>function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Categories());
                    return new TableGateway('categories', $dbAdapter, null, $resultSetPrototype);
                },
              [. . .]

2) Par la suite on demande que ArticleTable implemente l'interface ServiceLocatorAwareInterface. C'est ce que j'ai fait. En voici un extrait du code.

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\TableGateway\TableGateway;
/**
* Description of Article
*
* @author kouame
*/
class ArticleTable implements ServiceLocatorAwareInterface{
    // Table name in database
    protected $table ='Article';
    // Le service manager
    protected $sm;
   
    public function __construct(TableGateway $tableGateway)
    {
        $this->tableGateway = $tableGateway;
       
    }
    public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
    {
        $this->sm = $serviceLocator;
    }

    public function getServiceLocator()
    {
        return $this->sm;
    }

3) Par la suite, on me dit que je peut ainsi acceder a CategoriesTable a partir de ArticleTable en saisiant simplement ce code dans n'importe quel methode de ArticleTable:
$this->art=$This->getServiceLocator()->get('Site\Model\CategoriesTable');


Le problème est que quand j’exécute ce code, on me met le message d'erreur suivant:

Fatal error: Call to a member function get() on a non-object  ...

Quelqu'un aurait une solution a ce probleme et surtout comment la generaliser (comment acceder a un service a partir de n'importe ou dans le code)?

Hors ligne

 

#2 26-05-2014 23:40:30

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

Re: Probleme avec le service manager

Salut, comment récupères tu une instance de ArticleTable ?

Hors ligne

 

#3 27-05-2014 09:42:21

flobrflo
Membre
Lieu: Marseille
Date d'inscription: 26-04-2013
Messages: 376

Re: Probleme avec le service manager

Hello smile
tu devrais peut être passer par une factorie.

ah oui, je sais pas si c'est le copier collé, mais tu a un $This, on sait jamais smile

Hors ligne

 

#4 27-05-2014 10:03:02

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

Re: Probleme avec le service manager

Non ça vient pas du $This l'erreur est sur le get wink

Hors ligne

 

#5 27-05-2014 10:44:09

flobrflo
Membre
Lieu: Marseille
Date d'inscription: 26-04-2013
Messages: 376

Re: Probleme avec le service manager

Arf dommage ^^

(we je sais y avais peu de chance mais au moins c'est propre X_X)

Il aurait pas plus de chance avec ça?

Code:

[lang=php]
public function getServiceConfig() {
        return array(
            'factories' => array(
                 // Le service CategoriesTable
                'Site\Model\CategoriesTable' =>  function($sm) {
                    $tableGateway = $sm->get('CategoriesTableGateway');
                    $table = new Model\CategoriesTable($tableGateway);
                    return $table;
                },
                'CategoriesTableGateway'=>function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Categories());
                    return new TableGateway('categories', $dbAdapter, null, $resultSetPrototype);
                },
...

Hors ligne

 

#6 27-05-2014 11:54:56

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

Re: Probleme avec le service manager

Si mais le problème ne vient probablement pas de là.

Hors ligne

 

#7 27-05-2014 19:24:38

kouamepaul1
Nouveau membre
Date d'inscription: 26-05-2014
Messages: 3

Re: Probleme avec le service manager

Salut a tous, merci de vos questions. particulierement pour la question d'orkin, je veut simplement dire que jusqu'a present, je n'ai eu besoin de Modeles qu'a partir des Controllers. Hors le controleur implemente deja une interface qui rend disponible le serviceManager.

Donc a partir du controleur, pour avoir acces a ArticlaTable, je fais le code suivant:

$this->art=$This->getServiceLocator()->get('Site\Model\ArticleTable');

Quand je fait ce code ailleurs que dans le controleur j'obtiens le message
Fatal error: Call to a member function get() on a non-object  ...

Hors, au fur et a mesure que j'avance dans mon projet, ce probleme se generalise: J'ai besoin de certains services (notamment l'adapter, les modeles, ...) hors du controleur.

Hors ligne

 

#8 27-05-2014 21:29:35

JGreco
Administrateur
Date d'inscription: 22-12-2012
Messages: 432

Re: Probleme avec le service manager

Bonsoir,
C'est une mauvaise pratique d'appeler le serviceLocator dans le controller et ce sera enlevé dans la v3. Libre a toi de faire ce que tu veux toutefois a ce niveau là mais si ton application appelle le serviceLocator dans le controller ton controller assure une partie de la couche service et ce n'est son but ni ce pourquoi il existe. Dans le cadre d'une application maintenable dans le temps et évolutive et a plus forte raison si tu n'est pas seul a maintenir le projet il y a tout intérêt à créer une couche service.

Pour ton problème de "get on a non object" je te renvoie a mon ancien post sur ce forum http://www.z-f.fr/forum/viewtopic.php?id=9032
Tu risques d'apprendre beaucoup smile

Et si tu veux plus d'infos ou d'exemple de code je te renvoie ici :
https://github.com/jonathangreco/zf2-doctrine-tutorial

en espérant t'avoir aidé à comprendre plus a fond à partir de mes propres problèmes passés.

Dernière modification par JGreco (27-05-2014 21:37:52)


ZF2 et doctrine addict
profil stack overflow : http://stackoverflow.com/users/3333246/ … ab=profile

Hors ligne

 

#9 27-05-2014 22:35:18

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

Re: Probleme avec le service manager

Salut, que ça plante ailleurs c'est normal pour que l'interface ServiceLocatorAwareInterface ai un sens il faut que la classe qui l'implémente soit instanciée par le service manager (ou locator c'est la même chose). Ce qu'il se passe c'est que lorsque le service manager va instancier un nouvel objet il va faire bêtement un $class = new Class(). Mais ensuite il va faire un test supplémentaire : if ($class instanceof ServiceLocatorAwareInterface) { $class->setServiceLocator($serviceLocator) }.

Donc les contrôleurs le service locator est automatiquement injecté. Il sera probablement retiré dans le ZF3 (ça a été proposé) car il était mal utilisé et trop peu de développeurs utilisaient les fabriques.

Pour ton soucis j'ai répondu un peu trop vite ce matin, ça vient probablement du $This normalement c'est $this. Le message dit que tu appelles la fonction get sur quelque chose qui n'est pas un objet, ce quelque chose c'est getServiceLocator() et il ne peut pas être null dans un contrôleur.

Ensuite pour utiliser le service locator ailleurs que dans un contrôleur il suffit d'implémenter l'interface ServiceLocatorAwareInterface et d'utiliser le trait ServiceLocatorAwareTrait et tout se fait tout seul. La seule chose que tu dois faire c'est appeler tes services via le service locator

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