2010-05-10 6 views
1

Le manuel sur Zend_Application_Module_Autoloader stipule ce qui suit:Module autochargeur ZF

Lors de l'utilisation bootstraps du module avec Zend_Application, une instance de Zend_Application_Module_Autoloader sera créé par défaut pour chaque module discret, permettant aux ressources du module de chargement automatique.

Source:http://framework.zend.com/manual/zh/zend.loader.autoloader-resource.html#zend.loader.autoloader-resource.module

Cela me demande de créer une classe d'amorçage vide pour chacun de mes modules ou bien autoloading des ressources par module ne fonctionne pas avec l'accumulation dans autochargeur.

Maintenant, j'ai deux questions

  • Qu'est-ce qu'un module discret?
  • Est-il possible d'avoir cette autochargeur ressource enregistrée par défaut pour chaque module sans la nécessité de créer un fichier d'amorçage pour chaque module? Je veux qu'il soit disponible dans chaque module et créer autant de classes bootstrap vides est quelque chose que je préfère éviter.

Répondre

7

Je comprends votre réticence à ajouter une classe bootstrap vide à chaque module. Cependant, réfléchissez à la possibilité de réutilisation: si vous pouvez regrouper votre module séparément, vous pouvez ensuite le déposer dans une autre application plus tard, et le chargement automatique fonctionnera immédiatement, sans travail supplémentaire. C'était l'un des cas d'utilisation pour avoir des bootstraps de module, et pourquoi il fonctionne actuellement comme il le fait.

(« discrète » dans ce cas signifie « autonome », et ne fait pas partie du module « application ».)

Si vous ne voulez pas comment cela fonctionne, vous êtes libre d'omettre la module bootstrap - vous aurez simplement besoin d'ajouter un chargeur automatique de ressources pour le module vous-même. Cela peut être fait via une méthode de ressources bootstrap assez facilement. Cependant, comme quelqu'un l'a signalé plus tôt: pourquoi réinventer la roue quand quelque chose qui est testé et documenté fait le travail? :)

+2

Merci matthew ... vos arguments ont effectivement du sens. Je peux vivre avec des fichiers bootstrap vides et comme Travis et Jeremy dit qu'il viendra un temps que je vais avoir besoin de les bootstrap de toute façon, donc je vais juste faire face et utiliser des fichiers bootstrap vides :) – ChrisR

2

Les modules raison bootstraps permettent AUTOCHARGE est parce qu'ils étendent Zend_Application_Module_Bootstrap qui fixe le chargeur automatique dans le constructeur comme si

public function __construct($application) 
{ 
    //... 
    if ($application->hasOption('resourceloader')) { 
     $this->setOptions(array(
      'resourceloader' => $application->getOption('resourceloader') 
    )); 
    } 
    $this->initResourceLoader(); 
    //... 
} 

Cela va parce que la ressource de modules exécute le bootstrap pour chaque module dans la fonction init. ..

 foreach ($modules as $module => $moduleDirectory) { 
     $bootstrapClass = $this->_formatModuleName($module) . '_Bootstrap'; 
     if (!class_exists($bootstrapClass, false)) { 
      $bootstrapPath = dirname($moduleDirectory) . '/Bootstrap.php'; 
      if (file_exists($bootstrapPath)) { 
       $eMsgTpl = 'Bootstrap file found for module "%s" but bootstrap class "%s" not found'; 
       include_once $bootstrapPath; 
       if (($default != $module) 
        && !class_exists($bootstrapClass, false) 
       ) { 
        throw new Zend_Application_Resource_Exception(sprintf(
         $eMsgTpl, $module, $bootstrapClass 
        )); 
       } elseif ($default == $module) { 
        if (!class_exists($bootstrapClass, false)) { 
         $bootstrapClass = 'Bootstrap'; 
         if (!class_exists($bootstrapClass, false)) { 
          throw new Zend_Application_Resource_Exception(sprintf(
           $eMsgTpl, $module, $bootstrapClass 
          )); 
         } 
        } 
       } 
      } else { 
       continue; 
      } 
     } 

     if ($bootstrapClass == $curBootstrapClass) { 
      // If the found bootstrap class matches the one calling this 
      // resource, don't re-execute. 
      continue; 
     } 

     $moduleBootstrap = new $bootstrapClass($bootstrap); 
     $moduleBootstrap->bootstrap(); 
     $this->_bootstraps[$module] = $moduleBootstrap; 
    } 

La réponse courte est que si vous n'écrivez pas les fichiers bootstrap vides, vous aurez à abstraire une partie de ce qui fonctionne bien, le code bien testé en votre propre fichier d'amorçage global, puis perdre la flexibilité d'avoir des modules que vous bootstraps quand/si vous avez besoin de les amorcer plus tard dans votre application.

+0

Merci pour l'explication, il se sent juste contre-productif et pas vraiment La meilleure pratique consiste simplement à encombrer mes modules avec des classes bootstrap vides uniquement pour permettre le chargement de ressources spécifiques au module. En effet quand je veux amorcer un module je devrais ajouter un module bootstrap mais puisque dans TOUS les modules l'auto chargement de ressources devrait être disponible je me demandais s'il n'y avait pas quelque chose dans la portée d'application qui pourrait configurer ceci? – ChrisR

+1

Je comprends. S'ils sont vides, ils semblent tout simplement inutiles, mais selon mon expérience, il y a un moment dans chaque application où j'ai dû démarrer mon module. Je l'utilise pour définir des routes spécifiques au module personnalisé, en saisissant des fichiers de configuration formatés spécifiques pour les modules eux-mêmes, et d'autres choses comme ça. Vous pouvez facilement supprimer la nécessité pour elle de votre application en ajoutant ce code dans le fichier de démarrage, si cela vous dérange tant que ça, mais à mon humble avis, ce n'est pas la peine. – Travis

2

modules vous permettent de séparer votre application en préoccupations spécifiques. Mes applications les plus volumineuses auront souvent un module par défaut pour les utilisateurs et un module d'administration pour contenir toutes les fonctions administratives. J'utilise la structure de répertoires recommandée dans la section Structure de projet recommandée pour Zend Framework MVC Applications -> Structure du module de la Documentation Zend Framework.

Quant à votre deuxième question, la réponse est oui et non. Si vous voulez profiter de la fonctionnalité de chargement automatique par défaut (chargement Admin_Form_Settings à partir du répertoire admin/forme), vous aurez besoin d'un amorçage dans chaque module. Voir l'article sur Module Bootstraps in Zend Framework: Do's and Don'ts de Matthew Weier O'Phinney pour plus d'informations. Vous pouvez également consulter Google pour consulter l'article de Rob Allen intitulé «Bootstrapping modules in ZF 1.8 and up». Répondre à votre deuxième question: une technique que j'aime utiliser et qui ne nécessite pas de bootstraps vides dans chaque module consiste à placer toutes vos classes d'application dans le dossier lib de l'application, et à imiter la structure du répertoire de Zend Framework. Si mon application s'appelle Example, je vais créer un dossier nommé Example dans mon répertoire/lib. Mon formulaire d'inscription d'utilisateur serait placé dans/lib/Example/Form, et pourrait être nommé UserRegistration.php. Ma classe s'appellera Example_Form_UserRegistration. Autoloading mon formulaire nécessiterait le suivant dans le fichier Bootstrap.php:

protected function _initAppAutoload() { 

    $autoloader = Zend_Loader_Autoloader::getInstance(); 

    return $autoloader; 
} 

Mon application.ini comprendrait les lignes

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" 
resources.modules[] = 
autoloaderNamespaces[] = "Example_" 

En utilisant cette technique, vous devriez alors être en mesure de charger automatiquement une classe dans/lib/Exemple partout dans votre application sans placer bootstraps vides dans chaque module.

NOTE: J'ai essayé de poster des liens directement sur les documents et sur l'article de Rob Allen, mais comme je suis un nouveau type, je n'avais qu'un seul lien. Toutes mes excuses pour vous avoir demandé d'ajouter à Google des éléments qui devraient être des liens.

+0

Salut Jeremy, merci pour la réponse. Juste pour rendre les choses claires ... je sais ce que les modules sont et utilisent eux pour toujours, car ils sont devenus disponibles dans ZF mais je faisais référence à la « discrète » partie :) Et en ce qui concerne la deuxième question, je l'ai considéré comme l'importation presque tout dans l'espace de nommage de l'application, mais puisque la plupart des modules que je construis sont des modules de plugin plug and play, je voudrais garder tout ce qui concerne un module dans le dossier du module. – ChrisR

+0

Aha. Pour autant que je sache, la partie «discrète» décrit simplement les modules comme des parties distinctes et entièrement contenues de votre application. Je ne pense pas que ce soit destiné à être interprété comme un type de module différent. Confus, comme discret peut avoir une signification particulière dans les domaines techniques. Quant à votre deuxième question, compte tenu de vos besoins, je ne sais pas d'un moyen d'éviter l'ajout de données d'amorçage du module. Cependant, il y a beaucoup de développeurs ZF qui sont beaucoup plus intelligents que moi. Vous pouvez vérifier les liens au bas de l'article de Matthew pour de nouvelles idées. –

2

Il y a deux façons (que je connais) d'activer les autochargeurs de ressources de module. Le premier a été couvert de réponses ci-dessus, à savoir:

Ajouter la ligne de ressource de modules dans votre application.ini:

resources.modules[] = 

Et puis créez un fichier de démarrage du module vide.

Le second est d'ajouter la méthode bootstrap suivante à votre fichier de lancement de l'application à l'échelle (non-module):

protected function _initModuleAutoload() 
{ 
    $autoloader = new Zend_Application_Module_Autoloader(array(
     'namespace' => 'Foo', 
     'basePath' => APPLICATION_PATH . "/modules/Foo", 
    )); 
    return $autoloader; 
} 

Mais vous devez créer le chargeur automatique de chaque module individuellement. Personnellement, je préfère les fichiers bootstrap vides pour les raisons mentionnées ci-dessus - cela me semble plus manuel. Note: Je crois qu'il s'agit de la "méthode bootstrap resource" @weierophinney mentionnée ci-dessus.

0

Bootstrap:

$uri = explode('/',$_SERVER['REQUEST_URI']); 
if($uri['1'] == 'flok'){ 
    $flok = new Zend_Controller_Router_Route('flok/:controller/:action/:id/*', array('module' => 'flok', 'controller' => 'index', 'action' => 'index', 'id' =>null)); 
    $router->addRoute('flok', $flok); 

    $resourceLoader = new Zend_Application_Module_Autoloader(array(
     'basePath' => APPLICATION_PATH . "/flok/flok", 
     'namespace' => 'Flok', 
    )); 

    //Init 
    $frontController->registerPlugin(new Flok_Plugin_Init(),'flok'); 
    //Auth 
    $frontController->registerPlugin(new Flok_Plugin_Auth(),'flok'); 

    // dynamic modules 
    $ruta = APPLICATION_PATH.'/flok'; 
    foreach(scandir($ruta) as $mod) { 
     if(!is_dir($mod) and $mod != '.DS_Store'){ 
      $Modululflok = new Zend_Controller_Router_Route('flok/'.$mod.'/:controller/:action/:id/*', array('submodules' => 'flok','module' => $mod , 'controller' => 'index', 'action' => 'index', 'id' =>null)); 
      $router->addRoute($mod, $Modululflok); 
      $resourceLoader = new Zend_Application_Module_Autoloader(array(
       'basePath' => APPLICATION_PATH . "/flok/".$mod, 
       'namespace' => ucfirst($mod), 
      )); 
     } 
    } 

    $layout = Zend_Layout::getMvcInstance(); 

    $layout 
     ->setLayout('layout') 
     ->setLayoutPath(APPLICATION_PATH . '/flok/flok/views/scripts'); 

    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); 
    $viewRenderer->initView(); 
    $viewRenderer->view->addHelperPath(APPLICATION_PATH . '/flok/flok/helpers'); 
} else { 
    $default = new Zend_Controller_Router_Route('*', array('module' => 'default', 'controller' => 'index', 'action' => 'index')); 
    $router->addRoute('default', $default); 
} 

Cette aide pour insérer des données (menus, vues, etc.) dans le module de base:

class Zend_View_Helper_Models 
{ 
    public function Models($tipo) 
    { 
     // load modules 
     $ruta = APPLICATION_PATH.'/flok'; 
     foreach(scandir($ruta) as $mod) { 
      if(!is_dir($mod) and $mod != '.DS_Store'){ 
       $rutaphp = $ruta.'/'.$mod.'/'.$mod.'.php'; 
       if(file_exists($rutaphp)){ 
       include_once($rutaphp); 
        $modul = new $mod; 
        if(isset($modul->$tipo) and $modul->$tipo === true){ 
         $data = $tipo.'Data'; 
         $m[] = $modul->$data; 
        } 
       } 
      } 
     } 
     return $m; 
    } 

} 
+2

Bienvenue sur Stack Overflow, voulez-vous Veuillez communiquer vos réponses et vos questions en anglais afin que les personnes qui ne parlent pas l'espagnol puissent comprendre et en tirer profit. –

+0

OK, tout d'abord permettez-moi de traduire le texte, traducteur google, et pas beaucoup l'anglais vous remercie ... – user3422301

Questions connexes