Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 17-08-2009 02:07:53

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

Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Voici comment on peut configurer les modules d'une appli et les charger via le nouveau loader.
Avant on était obligé d'ajouter tous les paths nécessaires à l'include_path.
Ce n'est plus nécessaire.

Code:

// index.php
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH.'/config/application.ini'
);

Code:

;application.ini
...
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
; chargement des modules
resources.modules[] = module1
resources.modules[] = module2
...

Code:

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
...
    protected function _initModules()
    {
        $config = new Zend_Config($this->getOptions());        
        $modules = $config->resources->modules;
        
        // On charge chacun des modules configurés
        $loaders = array();        
        foreach ($modules->toArray() as $index => $module)
        {
            $loaders[$module] = new Zend_Application_Module_Autoloader(
            array(
            'namespace' => ucfirst($module), 
            'basePath'  => APPLICATION_PATH.'/modules/'.$module,
            ) );
            $loaders[$module]->addResourceType('View', 'views/mavue', 'View');
            $loaders[$module]->addResourceType('Model', 'models', 'Model');
            $loaders[$module]->addResourceType('Form', 'forms', 'Form');
        }
        
        ...
        
        return $loaders;
    }
...
?>

Par contre, avant on appelait une classe titi située dans le module toto comme cela:
$titi = new titi();

Maintenant, avec les nouveaux namespaces (pour éviter d'avoir 2 classes de même nom dans 2 dossiers différents), on apellera:
$titi = new Toto_Model_Titi(); // si la classe est dans /models
$titi = new Toto_Form_Titi(); // si la classe est dans /forms

Ca fait pas mal de code à changer, mais bon, pas le choix ...

Voila j'espère pouvoir aider, même si cela doit sembler évident à de nombreuses personnes.
Si jamais vous avez d'autres solutions je suis preneur.

Dernière modification par booradley (17-08-2009 02:12:09)

Hors ligne

 

#2 17-08-2009 11:08:37

Davjack
Membre
Date d'inscription: 06-02-2009
Messages: 32

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Sympa l'idée! Merci pour le partage ;-)

Hors ligne

 

#3 17-08-2009 12:42:08

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

De rien,
J'ai jugé bon de poster ceci car j'avais encore trouvé aucun exemple concret sur internet.


David

Hors ligne

 

#4 17-08-2009 14:56:00

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Salut,

En fait il n'est pas vraiment nécessaire d'ajouter tous les modules à l'include_path.

Si chaque module possède un bootstrap, par ex. module "News":

Code:

application/
    bootstrap.php       <--- bootstrap de l'application
modules/
    News/
        controllers/
        models/
        services/
        bootstrap.php    <--- boostrap pour le module news

Boostrap du module news:

Code:

<?php
/**
 * Module News - Bootstrap
 */
class News_Bootstrap extends Zend_Application_Module_Bootstrap
{   
    protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'News_',
            'basePath'  => dirname(__FILE__)
        ));
                
        return $autoloader;
    }
}

Zend_Application charge automatiquement le bootstrap des modules au travers de la ressource Zend_Application_Resource_Modules.
L'avantage d'avoir un fichier Bootstrap pour chaque module est de découpler le plus possible les modules de l'application, de conserver un bootstrap "propre" pour l'appli et de laisser chaque module gérer sa propre config. Il peut être également intéressant de récupérer le bootstrap d'un module pour exécuter certaines méthodes propres à ce modules à tout moment.

c.f Doc:

Code:

$resource = $bootstrap->getPluginResource('modules');
$moduleBootstraps = $resource->getExecutedBootstraps();
$newsBootstrap = $moduleBootstraps['news'];

Ton code à l'avantage de ne pas avoir à créer de fichier Bootstrap par module. En contre-partie tu perds l'idée de modules indépendants.

Petit détail sinon, ces deux lignes sont inutiles:

Code:

$loaders[$module]->addResourceType('Model', 'models', 'Model');
$loaders[$module]->addResourceType('Form', 'forms', 'Form');

Ces deux ressources sont dans les ressources par défaut de Zend_Application_Module_Autoloader.


A+ benjamin.


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

Hors ligne

 

#5 17-08-2009 16:01:20

tylerdurd
Membre
Date d'inscription: 22-07-2009
Messages: 75

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Salut,

merci à vous deux, ça m'a bien aidé.

Hors ligne

 

#6 17-08-2009 18:02:53

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Bonjour,

Dans l'idée d'un bootstrap unique, il n'y a toutefois pas besoin de déclarer tous les modules dans le fichier de conf, un moyen de les récupérer automatiquement pourrait être :

Code:

        $this->bootstrap('frontcontroller');
        $modules = array_keys(
            $this->getResource('frontcontroller')->getControllerDirectory()
        );
        // foreach ...

En revanche en ce qui concerne un bootstrap par module, quand on regarde la classe Zend_Application_Resource_Modules il s'avère qu'elle ne semble pas chercher de fichier de bootstrap pour le module déclaré "par défaut".
Cela signifie-t-il que tout traitement que l'on pourrait vouloir placer dans un bootstrap du module par défaut doit être écrit dans celui de l'application ?

Hors ligne

 

#7 18-08-2009 09:38:28

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Salut,

Tout dépend de l'arbo que tu décides d'utiliser.

Si ton module par défaut se trouve dans le dossier application, alors ce sera le bootstrap de ton application qui sera celui de ton module par défaut.

Sinon, si tu redéfinis le module par défaut par un module qui se trouve dans le dossiers des modules, il aura un bootstrap comme tous les autres. Tu ne fais qu'indiquer au Front Controller quel est le module à utiliser par défaut.

De base, il s'agit du dossier application.


A+ benjamin.


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

Hors ligne

 

#8 18-08-2009 10:15:14

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Dans le cas où le module par défaut est dans /modules/default/, il faut dès lors faire pointer "bootstrap.path" dans la config vers le bootstrap du module/default, non ?

Car dans la boucle qui parse tous les modules dans Zend_Application_Resource_Modules, le foreach force un continue; dès que le module parsé est celui déclaré par défaut. Cela sous-entends qu'à chaque chargement de l'application, le bootstrap du module par défaut est appelé en premier lieu, et c'est lui qui se charge via le plugin de resources Zend_Application_Resource_Modules de charger les autres bootstraps ?

Hors ligne

 

#9 18-08-2009 15:55:30

tylerdurd
Membre
Date d'inscription: 22-07-2009
Messages: 75

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Est-ce normal que lors du lancement de l'application, tous les bootstraps soient chargés ?

Je pensais que le bootstrap d'un module donné serait chargé lors du lancement de ce même module ...

Merci pour vos réponses.

Hors ligne

 

#10 19-08-2009 09:02:21

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

tylerdurd, c'est impossible. Le boostrap est ce qui intervient en premier. Le processus de routage n'a pas encore eut lieu et donc il est impossible de savoir quelle module est appelé.

Pour configurer un module qui sera utilisé, il faut passé par un plugin (c'est fait pour)


----
Gruiiik !

Hors ligne

 

#11 19-08-2009 09:34:41

tylerdurd
Membre
Date d'inscription: 22-07-2009
Messages: 75

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Je ne sais pas si je me suis bien fait comprendre ... et si j'ai suffisamment était précis aussi neutral

Je sais que le bootstrap est ce qui intervient en premier, cependant, dans mon application, j'ai un bootstrap par module (en plus de celui à la racine de 'application'), et je pensais que ces bootstrap là ne seraient pas tous chargés dès le début ... hors après une regard dans le code du ZF, ben tous les bootstraps sont chargés d'entrée ... (ceux situés dans les modules compris, c'est le chargement de ceux là qui m'interrogent)

Du coup, je ne vois plus trop l'utilité de mettre des fichiers de config (par exemple) propre à un module sachant qu'ils seront dans tous les cas chargés à tout moment ...

Hors ligne

 

#12 19-08-2009 10:03:57

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

L'utilité est la possibilité de le faire smile C'est tout l'intérêt du ZF.
Tu n'y trouves pt être pas l'utilité dans ton cas personnel (pas encore), mais peut-être que moi ou qqun d'autre y trouve une utilité.
Je suis prêt à parier que le developpeur y trouve une utilité  smile

Par exemple, moi je l'utilise pour initialisé certaines partie de mes menus. J'ai des helpers qui récupères des variables concernant le module courant (je me suis fait un helper getModuleOptions($moduleName = null))


----
Gruiiik !

Hors ligne

 

#13 19-08-2009 10:09:17

tylerdurd
Membre
Date d'inscription: 22-07-2009
Messages: 75

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Ok, merci, toutes mes excuses ... J'avoue avoir pensé dans mon cas ... roll

Hors ligne

 

#14 19-08-2009 11:03:26

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Salut,

@Eureka:

Ce n'est pas le module par défaut qui charge les autres. C'est simplement que s'il s'agit du module par défaut, le bootstrap a logiquement déjà été chargé et donc c'est inutile de repasser dedans. Par contre la boucle continue et charge tous les autres bootstrap des modules.

@tylerdurd:

Tu peux avoir besoin d'accéder à tous tes modules à tout moment dans l'application, c'est donc nécessaire d'initialiser les modules au préalable et donc de systématiquement charger les bootstrap.



A+ benjamin.


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

Hors ligne

 

#15 19-08-2009 13:56:42

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Delprog,
Je vais suivre ton conseil de créer un bootstrap par module.
En effet la doc indique:

Code:

$resource = $bootstrap->getPluginResource('modules');
$moduleBootstraps = $resource->getExecutedBootstraps();
$newsBootstrap = $moduleBootstraps['news'];

Mais $bootstrap n'est pas défini dans mon boostrap.
J'ai bien essayé :

Code:

$resource = $this->getPluginResource('modules');
ou
$resource = $this->bootstrap->getPluginResource('modules');

Mais j'arrive pas a trouver a quel classe appartient cet méthode getPluginResource().

Est ce que c'est lié au getOptions() qui permet de récupérer les infos de application.ini?

Hors ligne

 

#16 19-08-2009 14:15:09

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Salut,

Code:

$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');

Tu peux ainsi accéder à toutes les ressources n'importe où.

Edit : sekaijin a mis à disposition des diagrammes bien pratiques, n'hésitez pas à vous en servir. Entre autre:
http://www.z-f.fr/forum/viewtopic.php?id=3608

A+ benjamin.

Dernière modification par Delprog (19-08-2009 14:19:55)


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

Hors ligne

 

#17 19-08-2009 15:17:54

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

hello,

Delprog a écrit:

@Eureka:

Ce n'est pas le module par défaut qui charge les autres. C'est simplement que s'il s'agit du module par défaut, le bootstrap a logiquement déjà été chargé et donc c'est inutile de repasser dedans. Par contre la boucle continue et charge tous les autres bootstrap des modules.

Quand je parlais de "module par défaut qui charge les autres" je sous-entendais que c'est le bootstrap du module par défaut qui déclenche le plugin de ressource Z_A_Resource_Modules qui charge les autres bootstraps.

Merci pour ta réponse, ça répond à mon questionnement.

Hors ligne

 

#18 19-08-2009 16:28:19

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Delprog,
j'ai ajouté cette ligne dans mon bootstrap par défaut:

Code:

 $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');

Ca fait carrément crasher Apache.
De plus je comprends pas comment ca fonctionne.
Tout ce que je veux c'est qu'a partir de mon bootstrap par défault, les bootsraps de mes autres modules soient appelés

Code:

    protected function _initAutoload()
    {     
        
        $config = new Zend_Config($this->getOptions());        
        $modules = $config->resources->modules;

        // On charge chacun des modules configurés
        $loaders = array();
        foreach ($modules->toArray() as $index => $module)
        {
            
            $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$resource = $bootstrap->getPluginResource('modules');
            $bootstrap = $moduleBootstraps[$module];
        
            /*
            $loaders[$module] = new Zend_Application_Module_Autoloader(
            array(
            'namespace' => ucfirst($module), //.'_'
            'basePath'  => APPLICATION_PATH.'/modules/'.$module,
            ) );
            $loaders[$module]->addResourceType('View', 'views/exotica', 'View');
            $loaders[$module]->addResourceType('Helper', 'helpers', 'Helper');
*/
        }        ...
        
        return $loaders;
    }

Quelqu'un peut-il me dire ce qui cloche?

Hors ligne

 

#19 19-08-2009 16:45:17

tylerdurd
Membre
Date d'inscription: 22-07-2009
Messages: 75

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Il me semble qu'ils sont chargés automatiquement, tu n'as pas besoin de ta boucle foreach.

Fais bien hériter les Bootstraps (situés dans les modules) de la classe Zend_Application_Module_Bootstrap
Il faut également que le nom de classe de ton Bootstrap soit de la forme "NomModule_Bootstrap"

Hors ligne

 

#20 19-08-2009 16:52:03

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

A priori je dirais :

Soit ajouter dans le fichier de configuration la ligne

Code:

resources.modules = ''

qui se chargera d'appeler le plugin de ressource Zend_Application_Resouce_Modules qui instanciera les boostraps de chaque module.

Soit dans ton bootstrap par défaut de faire

Code:

$this->bootstrap('modules'); // pour instancier la ressource (et les bootstraps de chaque module)
$bootstraps = $this->getResource('modules') // au besoin récupére le tableau des bootstrap nés de l'instanciation

Il me semble que les boostraps de modules embarque à leur création une instance de Zend_Application_Module_Autoloader (probablement initialisé avec des chemins par défaut). Du coup il doit être possible de le modifier soit dans ton bootstrap principal en récupérant les bootstraps comme ci-dessus, soit dans les bootsraps eux-même.

Hors ligne

 

#21 19-08-2009 17:01:09

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Si je définis moi même dans mon application.ini les modules à charger c'est que je n'utilise que 15 modules sur 30.
En effet j'ai plusieurs applications qui tournent et chacun utilise l'un ou l'autre des modules disponibles.
C'est la raison pour laquelle j'utilise un foreach.

Code:

;application.ini
resources.modules[] = module24
resources.modules[] = module745
resources.modules[] = module16

En tout cas ca crashe plus,
mes bootstrap de modules étendaient Zend_Application_Bootstrap_Bootstrap et non Zend_Application_Module_Bootstrap.

Par contre si j'ajoute un bootstrap au module 99 (alors que celui ci n'est pas chargé via mon application.ini, il est quand même appelé!
Pas cool!!!

Dernière modification par booradley (19-08-2009 17:06:04)

Hors ligne

 

#22 19-08-2009 17:07:55

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Je ne sais pas si l'idée est bonne, mais dans application.ini, tu pourrais (s'il n'y a pas d'effet de bord) :

Ne pas mettre cette ligne (si elle est présente) :

Code:

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

car elle définit le chemin des modules et ZF considères donc chaque sous-dossier comme un module à utiliser.

Mais plutôt utiliser :

Code:

resources.frontController.controllerDirectory.<ModuleName> = APPLICATION_PATH "/modules/<ModuleName>/controllers"
// mettre les 15 à utiliser

qui ici va forcer le plugin de ressource Z_A_R_Modules à ne considérer comme modules que ceux spécifiés dans la config

Dernière modification par Eureka (19-08-2009 17:21:04)

Hors ligne

 

#23 19-08-2009 17:25:20

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Oui c'est une idée mais bon je trouve pas ca tres optimal.
Je pense donc qu'il serait bon dans mon cas d'appeler mes bootstrap explicitement dans mon code et de désactiver l'appel automatique de Zend.
Une idée sur le sujet?

Hors ligne

 

#24 21-08-2009 10:11:32

Eureka
Membre
Date d'inscription: 18-07-2009
Messages: 81

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

salut,

Pour que ZF ne charge pas les bootstraps il suffit ne pas charger la ressource Zend_Application_Resource_Modules car c'est elle qui les charge tous dès lors que resources.frontController.moduleDirectory est renseigné en config.

Du coup pour les charger manuellement je pense qu'il faut prendre exemple sur la méthode _init() de la ressource, à priori il suffirait de la copier/coller dans ta méthode d'initialisation à toi, et de faire en sorte que la boucle parsant les modules se base sur ta liste de modules et non sur la liste des modules trouvé dans les répertoires.

Code:

// Z_A_Resource_Modules utilise globalement :
array_keys($front->getControllerDirectory());

// et toi tu l'adaptes à ton besoin, via
$config->resources->modules;

Dernière modification par Eureka (21-08-2009 10:12:03)

Hors ligne

 

#25 26-08-2009 17:01:54

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

Re: Zend_1.8]: Chargement des modules avec Zend_Application et autoloader

Oui je vois bien mais il faudrait court-circuiter l'appel à Z_A_Resource_Modules.
Et là je vois pas comment faire.

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