Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 08-10-2010 13:26:06

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Multiples modules et bootstrap

Bonjour,

Voila je suis actuellement en train de faire un site web qui comprendra deux parties via Z-F.
(Un frontend et un backend.. normal jusque là wink)

Après lecture de différents posts, il est indiqué de faire deux modules (j'ai utilisé zend_tool pour cela).
Maintenant quand j'accède à monsite.com je souhaiterai que le module par défaut soit celui du frontend.
Et monsite.com/admin soit celui du backend.

Pour cela à ce que j'ai compris je dois :

1. Changer les routes par défauts (Route_Module je crois) pour utiliser le bon MVC (model,view,controller) ainsi que le layout par défaut du module.

2. Je dois le faire dans application/bootstrap.php (j'en profite également pour initialiser une connexion à la base de données générique)

Mais après, je suis complètement noyé, je ne sais absolument pas ce qu'il faut envoyer comme méthode..

Des fois je vois Zend_FrontController::getInstance();, des fois $this->bootstrap('bootstrap')->getResource('frontController')..

Plus je lis de code, et plus j'ai l'impression que c'est bordélique..

J'avoue avoir pas mal de difficulté à comprendre le système de Zend et le bootstrap.. (fichier de démarrage, permet de préparer le MVC de façon globale pour toute l'application avant que le router passe à l'action, est ce bien cela?)..

$this dans le bootstrap fait référence à lui même.
Pourquoi dois je faire $this->bootstrap('FrontController') ?

Je souhaiterai également factoriser et partager entre ces deux modules des classes que je pourrai surcharger si besoin est dans chaque modules.

Exemple :
-> models/utilisateurs.php (classe par défaut qui contient des méthodes génériques, genre insert, update..)
-> models/backend/utilisateurs.php (classe qui surchargera le model par défaut avec des besoins spécifiques)

Enfin, pour que l'application soit modulable, je souhaiterai faire deux bootstraps par modules qui surchargerai le bootstrap d'origine.

Ainsi je pourrais faire un truc genre :
_initDb dans tous les modules (application/bootstrap.php)
_initDb dans le module backend pour le lier à une autre base de données..

Comment puis je faire cela ? Est ce que quelqu'un pourrait m'expliquer le fonctionnement MVC, parce que entre "Resources, Plugins, Bootstraps, Modules" je commence à mélanger toutes les pédales.

Merci pour votre aide

Hors ligne

 

#2 08-10-2010 14:58:41

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: Multiples modules et bootstrap

Salut,

Ça parait compliqué au premier abord mais en réalité c'est assez simple.

Une requête HTTP est envoyée par le client, apache (ou autre) grâce au virtualhost redirige cette requête vers le fichier index.php de ton application.

A partir de là c'est le ZF qui va traiter la requête dans un cheminement très logique. Je te donne les grandes lignes.

1ère Etape : Bootstrapping

A ce stade là, le MVC n'entre pas encore en jeu. Le bootstrapping est la phase d'initialisation de l'application.
Le composant en charge de cette initialisation est Zend_Application.

Il y a deux méthodes pour initialiser les différentes ressources de l'application avec Zend_Application. Soit par des plugins de ressources, qui sont des classes d'initialisation dédiées à des ressources en particulier. Soit par des méthodes d'initialisation présentes dans le fichier Bootstrap.php.

Zend_Application va parcourir les fichiers de configuration et exécuter chaque plugin de ressource dont l'application a besoin et va également exécuter chaque méthode d'initialisation du Bootstrap principal de l'application (le fichier application/Bootstrap.php).

Il va aussi vérifier pour chaque module qu'un Bootstrap existe et si oui va l'exécuter. Peu importe le module demandé dans l'url, il va tous les exécuter.

Une fois la phase d'initialisation terminée, la main est donnée au contrôleur frontal de l'application ($application->run()) et c'est là que commence la boucle de Dispatching.


2ème Etape : Contrôleur frontal et dispatch

Toujours pas de MVC ici smile

Un objet Request et un objet Response sont créés.

Le dispatcheur va chercher une route (parmis celles chargées lors de l'initialisation) qui match avec l'url invoquée.

Une fois la route déterminée, l'url va être découpée et c'est de là que vont être extraits le module, le contrôleur et l'action à exécuter, on y arrive smile

Toutes ces informations sont données à l'objet Request qui est transporté de couches en couches dans l'application.

3ème Etape : Les contrôleurs d'actions

Une fois l'objet Request nourri, le process de dispatch des contrôleurs d'action commence. Pour faire simple c'est à ce moment là que l'action de ton contrôleur est invoquée.

Une fois toutes les actions (de contrôleurs) terminées, l'objet Response est nourri et retourne dans le contrôleur frontal pour enfin être rendu au client.


Ce sont les (très) grandes lignes, en réalité beaucoup de choses sont exécutées entre chaque étape (plugins, helpers, etc.). Je te suggère de jeter un coup d'oeil à ce workflow : http://nethands.de/download/zenddispatch_en.pdf

Il n'inclue pas la phase d'initialisation parce que Zend_Application n'existait pas à ce moment là, mais ça donne une bonne idée du processus de dispatch.


Concernant ton problème initial. Il est possible de paramétrer le module par défaut & co dans le fichier de configuration (application.ini) avec la ressource frontcontroller :

Code:

;====== Resource frontController
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectoryName = controllers
resources.frontController.defaultModule = "frontend"

Inutile d'utiliser le fichier de Bootstrap dans ce cas là donc, Zend_Application va se démerder comme un grand smile

Pour partager des classes, aucun problème. Les classes de l'application et des modules sont chargées par l'autoloader grâce aux différents espaces de noms que tu leur a attribué.

Exemples :

Arborescence (simplifiée) :

Code:

application/
    models/
        User.php
    modules/
        frontend/
            models/
            Bootstrap.php
        backend/
            models/
                MonEntite.php
            Bootstrap.php
    Bootstrap.php

Bootstrap de l'application :

Code:

    protected function _initAutoload()
    {        
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => '',
            'basePath'  => dirname(__FILE__),
        ));
 
        return $autoloader;
    }

Bootstrap du module backend (qui n'est pas obligatoire d'ailleurs) :

Code:

    protected function _initAutoload()
    {        
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Backend_',
            'basePath'  => dirname(__FILE__),
        ));
 
        return $autoloader;
    }

La classe de modèle User (application/models/User.php dans l'exemple) sera Model_User et pourra être utilisée partout dans l'application, modules compris.

La classe MonEntite  (application/models/backend/MonEntite.php) sera Backend_Model_MonEntite, et ne devrait être utilisée que dans le module Backend. Je dis "devrait" parce qu'en vérité tu peux l'utiliser où tu veux, mais après c'est un problème de logique smile

Je t'invite à lire attentivement la documentation du ZF à ce sujet.


A+ benjamin.

Dernière modification par Delprog (08-10-2010 15:01:40)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#3 08-10-2010 15:03:28

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Re: Multiples modules et bootstrap

Merci, mais quelle est la différence entre un plug-in et une ressource ?

A ce que j'ai compris, la ressource permet d'utiliser des éléments qui ont été définis dans application.ini

Hors ligne

 

#4 08-10-2010 15:25:44

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: Multiples modules et bootstrap

Une ressource est un composant de l'application (Le contrôleur frontal, Zend_Mail, Zend_View, Zend_Translate, etc. etc.).

Un plugin est une classe qui peut être greffée à l'application sans aucune modification particulière (c'est la définition même d'un plugin). Il existe différents types de plugins dans le ZF.

- Plugin de ressource (de zend application) : permet d'initialiser une ressource.
- Plugin de contrôleur frontal : permet d'intervenir à différents moments pendant la boucle de dispatch.
- Aide d'action : c'est un pattern à part entière mais pourrait être appelé "plugin d'action". Les aides d'actions permettent d'ajouter des fonctionnalités aux contrôleurs d'actions.
- Aide de vue : idem, mais pour la vue. Permet de factoriser certaines parties des vues, parfait pour un widget par ex.


A+ benjamin.

Dernière modification par Delprog (08-10-2010 15:34:19)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#5 08-10-2010 17:40:23

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Re: Multiples modules et bootstrap

erf.. je suis désolé, je ne comprends pas..

je viens d'essayer de faire les redirections vers les modules

le module backend, et le module frontend

Je souhaite utiliser le bootstrap.php pour le faire, dans la doc de Zend, ils disent qu'il suffit de mettre un truc du genre :

Code:

        $front->setControllerDirectory(
            array(
                'default' => '../application/modules/frontend/controllers',
                'backend' => '../application/modules/backend/controllers'
            )
        );

Et juste en dessus ils donnent des urls :
/monsite.com/backend --> module backend, controlleur Index, defaultAction

Est ce que le nom 'backend' du segment de l'URL (ou ca n'a rien a voir) doit correspondre au nom du module obligatoirement ?

Si je met par exemple, admin --> path /backend

Je pourrai appeller monsite.com/admin ? ou ca ne va pas marcher ?

Si je met un truc comme :

Code:

$router->addRoute('/admin/*',array(
                                        'controller'=>'index','action'=>'default','module'=>'backend')

Ça ne marche pas (et pourtant ca serait assez logique de le faire de cette manière)

J'ai du mal a comprendre le mapping entre : le nom de la section de l'url (ici admin) qui devrait théoriquement représenter le nom du module, son chemin d'accès, et le système de routage..

Dans l'exemple ci-dessus tu apportes la solution en indiquant le defaultModule, mais comment puis je faire ca pour l'admin ?

A mon avis, essayer de router l'url avec du routage ca ne sert a rien car l'url du lien peut tout à fait ne pas correspondre avec le "nom du module"

/admin/ /administration/ /backend/ peuvent renvoyer au même module. Donc faire un système de routage ne doit normalement pas être utile dans ce cas.. mais vu que je mélange les pinceaux j'ai du mal à faire la distinction.

De plus, faire un appel dans le bootstrap.php du controleur Frontal Zend_Controller_Front::getInstance(); ne donne pas le meme résultat que $this->bootstrap('bootstrap')->getResource('FrontController'); ... c'est assez étonnant car le controller Frontal est un singleton.. donc faire un debug de getInstance() ou de getResource() ca devrait me donner exactement la meme chose.. or getResource il y a plus de choses dans l'objet..

Désolé pour mes questions, mais franchement je comprends plus du tout et la documentation de Zend (anglais comme francais) n'est pas très succinte.. j'espère que c'est la phase la plus difficile pour appréhender le framework parce que ca va faire 2 jours que je suis dessus et j'ai pas l'impression d'avancer des masses (je suis convaincu de l'utilité d'utiliser un framework.. mais bon..)

Merci pour ton aide en tout cas !

Hors ligne

 

#6 10-10-2010 10:46:43

Delprog
Administrateur
Date d'inscription: 29-09-2008
Messages: 670

Re: Multiples modules et bootstrap

Hello,

Je pense que tu as compris l'idée, maintenant c'est une question de configuration.

Attention, la documentation du ZF, notamment celle de Zend_Controller n'est pas forcément très à jour et après les changements apportés par Zend_Application depuis la version 1.8 ça peut ne plus correspondre (même si le code proposé reste encore possible).

Donc, déjà, utilises-tu une version antérieur à la 1.8 ?

Comme tu l'as dis le nom du module doit être présent dans l'url, c'est grâce à l'url que le dispatcher va pouvoir trouver une route qui correspond et découper en module/vue/contrôleur.

Si tu veux utiliser des routes différentes de celles par défaut pour accéder à un module, tu dois effectivement les spécifier.

La configuration suivante doit fonctionner (avec ZF > 1.8), si c'est pas le cas, le problème vient d'ailleurs. Ça se passe dans le fichier application.ini.

Code:

;====== Resource frontController
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectoryName = controllers
resources.frontController.defaultModule = "frontend"

;====== Resource router
resources.router.routes.admin.type = Zend_Controller_Router_Route
resources.router.routes.admin.route = "/admin/*"
resources.router.routes.admin.defaults.module = backend
resources.router.routes.admin.defaults.controller = index
resources.router.routes.admin.defaults.action = index

Par défaut:
http://www.ton-site.com/    <--- module: frontend, controller: index, action: index
http://www.ton-site.com/admin/   <--- module: backend, controller: index, action: index
http://www.ton-site.com/backend/   <--- idem

Le chemin dans le système de fichier comporte le nom du module (ici backend).

Tout est basé sur le routage. Il y a une route par défaut (/:module/:controller/:action) et ensuite à toi de créer les routes dont tu as besoin, c'est tout à fait logique de procéder de cette manière.


A+ benjamin.

Dernière modification par Delprog (10-10-2010 10:47:50)


http://www.anonymation.com/ - anonymation - Studio de création.
http://code.anonymation.com/ - anonymation - blog - développement et architecture web

Hors ligne

 

#7 10-10-2010 14:14:00

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Re: Multiples modules et bootstrap

Merci pour ta réponse. J'utilise zend v 1.10.6
Petite question subsidiaire vaut-il mieux utiliser bootstrap.php ou application.ini ? Y a t-il une différences notable entre les deux ?

Enfin, au niveau du mécanisme du MVC si j'ai bien compris cela marche de cette manière corrigez moi si je me trompe :

1. La requête arrive sur index.php

2. Démarrage de Zend_Application, initialisation du Zend_Loader par défaut, configuration des éléments globaux à tout le MVC (attribution des ressources automatique qui ont été définies via application.ini) (différence avec les plugs-in ici ?)

3. Lancement du bootstrap.php qui est la dernière possibilité de configurer le MVC

4. Configuration du Zend_Controller_Front ( Zend_Controller_Front::getIstance() ne donne pas le même résultat que $this->bootstrap('bootstrap')->getResource('FrontController') .. pourquoi ? (Alors que front Controller est un singleton... pourquoi avec $this->bootstrap->getResource('FrontController') je vois "plus d'éléments" (ressources) alors que je ne vois que la resource FrontController (j'ai fais un Zend_Debug::dump de l'instance en question)..  Pourquoi doit on faire $this->bootstrap('bootstrap') alors que $this-> (au niveau du bootstrap.php) c'est sensé être cela ? Je comprends pas cette différence surtout que ce Controller_Front est un singleton. Donc ce qu'on attribut par Zend_Application de manière automatique ou manuellement, Zend_Controller_Front doit avoir la même configuration (mêmes attributs complétés) l'appel au FrontController n'est qu'une question selon moi de gout, faire new Zend_Controller_Front ou Zend_Controller_Front::getInstance() c'est pareil.. (non ?hmm)

5.Lancement du système de routage, définitions des modules/controlleurs/actions et attributions des "petits" controlleurs), création de la route.

(Quel est l'intérêt ici d'avoir la possibilité d'avoir des méthodes comme routeLookStartup() routeShutdown() ?)
J'ai bien compris que ce sont des moyens d'agir globalement sur toutes les routes avant et après l'attribution.. mais je ne vois pas de cas concret sur l'intérêt de les utiliser excepté que ca factorise le traitement sur tous les modules/controleurs

6. Lancement du dispatcher (boucle) qui va trouver le bon module/controlleur/action. Tant que dispatcher = true, il cherche les bonnes combinaison. Dès qu'il a trouvé un action, il met le dispatcher à false et le traitement par l'action peut commencer. L'action peut également "balancer" la requete vers un autre module/controlleur sans renvoyer de vue (méthode forward) qui aura pour effet de mettre dispatcher à true. C'est un peu comme une patate chaude qu'on se rebalance.. est ce qu'il essayes toutefois de repasser par le l'action "actuelle" ? (je suppose que non sinon ca devient une boucle infinie).

A ce niveau les méthodes preDispatch() / postDispatch() permettent de faire des traitement sur l'ensemble des controlleurs/modules de manière globale. Encore une fois il y a quelqu'un qui peut me donner un exemple d'utilisation ? (Pourquoi ne pas par exemple instancier ici Zend_Db plutôt qu'au démarrage de l'application ?)
Même chose que dans le point 5 excepté qu'on factorise le traitement sur l'ensemble des contrôleurs du modules et pas du module N..

7. Bref, le "petit" controlleur est trouvé, on exécute alors le traitement de _initAction (traitement commun), puis l'action en question (ou defaultAction si non trouvée)). Encore une fois permet de factoriser des traitement locaux sur toutes les actions de ce contrôleur.

8. Une vue est préparé (ou autre), l'action alors transmet à son controller la réponse sous la forme d'un objet response, qui est renvoyé via le controlleur Frontal.

La réponse peut-être "préparé" en amont par le controlleur frontal, par exemple pour mettre l'encodage sur utf-8..

9. Enfin le controlleur frontal execute la requete (sortie vers display, flux rss, téléchargement d'un fichier..) en fonction du header qui aura été définit dans l'objet de réponse.

Ai je juste ?

A ce niveau j'entends beaucoup parler des Helper (ViewHelper (ex : flashMessenger)), Helper d'actions, de vue.. C'est également la ou ca devient un peu compliqué comment faire le distinction entre : resource, plugin, helper ? Ou doit on les définir normalement ? (Pour moi ca semble logique de les définir a leur niveau, ainsi a quoi bon configurer le MVC avec une resource Zend_Db puisque on va pas l'utiliser tout de suite ? Pourquoi ne pas l'instancier au niveau du preDispatch (qui se trouve le plus proche de l'action qu'on va réaliser.. ?)

Désolé pour toutes ces questions, mais je pense que pour utiliser Zend il est fondamental que je comprenne bien les concepts de base et ca doit être clair dans ma tête sinon je vais aller au casse pipe lol

Merci pour ton aide Delprog en tout cas j'apprécie et j'espère que mon post / questions permettrons aux autres de mieux comprendre l'architecture du MVC.

Dernière modification par xenesis (10-10-2010 14:22:05)

Hors ligne

 

#8 11-10-2010 13:13:55

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Re: Multiples modules et bootstrap

Code:

        $front = Zend_Controller_Front::getInstance();
        $front->setControllerDirectory(
            array(
            'default' => $this->root.'/application/modules/frontend/controllers',
            'backend' => $this->root.'/application/modules/backend/controllers'
        ));

Ce code devrait marcher.. rien à faire.. je ne comprends pas

Hors ligne

 

#9 14-10-2010 11:47:45

xenesis
Membre
Date d'inscription: 25-08-2009
Messages: 23

Re: Multiples modules et bootstrap

up

Hors ligne

 

#10 14-10-2010 22:32:12

probitaille
Membre
Lieu: Montréal
Date d'inscription: 20-04-2009
Messages: 336
Site web

Re: Multiples modules et bootstrap

Peut-être que ça peut t'aider:

http://www.z-f.fr/forum/viewtopic.php?id=5223

Hors ligne

 

#11 07-07-2011 17:08:16

virulento
Nouveau membre
Lieu: Nantes 44 (FRANCE)
Date d'inscription: 19-05-2011
Messages: 2

Re: Multiples modules et bootstrap

Je viens de finir ma première application sous Zend, une petite appli pas très compliqué et là je commence une autre mais j'ai besoin de la faire par modules. Je suis tombé sur ce fil et je voudrais remercier Delprog car pour moi tout marche parfaitement en suivant ses indications.

J'ai créé mes modules avec Zend_Tools et j'ai renseigné mes routes dans le fichier de config, j'ai ajouté un bootstrap.php à la racine de caque module avec une méthode _initRouter() et j'ai créé un contrôleur de base pour chaque module Index avec son action de base index. Ensuite j'ai testé tous les url's de mon appli et pour moi ça a marché du premier coup!!! cool cool

Merci beaucoup Delprog!!! winkwinkwinkwink

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