2008-11-03 4 views
8

Ich arbeite an der Implementierung von Zend Framework in einem bestehenden Projekt mit einem öffentlichen Marketingbereich, einem privaten Mitgliederbereich, einer Verwaltungssite und einer Marketingkampagnen-Verwaltungssite. Derzeit sind diese mit den Controller-Skripts für den Marketingbereich und den Mitgliederbereich, die alle unter dem Stamm der Site und dann einem separaten Ordner für Admin und einem anderen Ordner für die Marketingkampagnen-Site sind, schlecht organisiert.Wie verwenden Sie die gleichen Modelle in verschiedenen Modulen im Zend Framework?

Bei der Implementierung des Zend Framework möchte ich in der Lage sein, die Controller und Ansichten in Module zu teilen (eine für den Mitgliederbereich, eine für den öffentlichen Marketingbereich, eine für die Admin-Site und eine für das Marketing) Ich muss jedoch jedes Modul auf die gleichen Modelle verweisen können, da alle drei Komponenten in derselben Datenbank und auf denselben Geschäftsobjekten arbeiten.

Ich konnte jedoch keine Informationen finden, wie dies in der Dokumentation zu tun ist. Kann jemand Hilfe mit einem Link auf, wie man dies tut, oder einigen einfachen Anweisungen, wie man es erreicht?

Antwort

9

Was ich tue ist, allgemeine Klassen in einem "Bibliothek" Verzeichnis außerhalb der Modulhierarchie zu halten. Dann setze ich meine INCLUDE_PATH, um das "models" -Verzeichnis des jeweiligen Moduls plus das gemeinsame Verzeichnis "library" zu verwenden.

docroot/ 
    index.php 
application/ 
    library/ <-- common classes go here 
    default/ 
     controllers/ 
     models/ 
     views/ 
    members/ 
     controllers/ 
     models/ 
     views/ 
    admin/ 
     controllers/ 
     models/ 
     views/ 
. . . 

In meinem Bootstrap-Skript, würde ich "application/library/" die INCLUDE_PATH hinzuzufügen. Dann würde ich in die init() Funktion jedes Controllers das Verzeichnis "models/" dieses Moduls zu INCLUDE_PATH hinzufügen.

edit: Funktionen wie setControllerDirectory() und setModuleDirectory() fügen Sie nicht die entsprechenden Modelle Verzeichnisse auf den INCLUDE_PATH. Sie müssen dies auf jeden Fall selbst tun. Hier ist ein Beispiel dafür, wie es zu tun:

$app = APPLICATION_HOME; // you should define this in your bootstrap 
$d = DIRECTORY_SEPARATOR; 
$module = $this->_request->getModuleName(); // available after routing 
set_include_path(
    join(PATH_SEPARATOR, 
    array(
     "$app{$d}library", 
     "$app{$d}$module{$d}models", 
     get_include_path() 
    ) 
) 
); 

Sie könnten die „library“ auf Ihren Weg in dem Bootstrap hinzufügen, aber Sie können das „models“ Verzeichnis für das richtige Modul in der Bootstrap nicht hinzufügen, weil Das Modul hängt vom Routing ab. Einige Leute tun dies in der init() Methode ihrer Controller, und einige Leute schreiben ein Plugin für den preDispatch-Hook des ActionControllers, um die INCLUDE_PATH zu setzen.

+0

Gibt es einen Grund, die Sie verwenden addControllerDirectory nicht(), anstatt einen Wert an die INCLUDE_PATH Zugabe? –

+0

addControllerDirectory() fügt meines Include-Pfad das entsprechende Modellverzeichnis nicht hinzu, soweit ich weiß. Siehe Beispiele in meiner Bearbeitung oben. –

3

Dies kann auch durch eine Namenskonvention erreicht werden, um Zend_Loader zu folgen. Bewahren Sie Ihre Modelldateien im Ordner models unter ihrem Modulordner auf. Benennen Sie sie als Module_Models_ModelName und speichern Sie sie in einem Dateinamen ModelName.php im models-Ordner für dieses Modul. Stellen Sie sicher, dass sich der Anwendungsordner in Ihrem Include-Pfad befindet. Wenn Sie Zend_Loader zum automatischen Laden verwenden, können Sie die Modelle einfach anhand ihres Klassennamens referenzieren.

Dies hat den Vorteil, dass Sie Ihren Modellcode mit dem eigentlichen Modul gruppieren. Dadurch bleibt das Modul in einer einzigen Ordnerstruktur enthalten, was die Kapselung unterstützt. Dies wird auch in Zukunft helfen, wenn Sie das Modul in ein anderes Projekt portieren müssen.

0

Ich habe das gleiche Problem. Bills Antwort passt nicht zu mir - denn ich tendiere dazu, meine Module zu teilen, nicht durch "wer sie sieht", sondern durch "was sie tun". ZB kann ein "Forum-Modul" sowohl von Admin als auch von der Öffentlichkeit verwaltet werden. Ich versuche, Front-End-Module zu haben, wie Admin, Mitglieder, öffentliche - aber diese verwenden dann andere Module wie "Forum/validepost", "Forum/Show Benutzer persönliche Informationen". Wenn jemand herausfinden könnte, wie er ein Backend-Modul vor der Öffentlichkeit schützt, wäre das praktisch. Ich denke, ACL kann der Schlüssel sein, aber es macht mich immer noch nervös mit Zugriff durch Objekte wie 'Dateisystem/.htaccess' etc.

gesteuert

Antwort auf PHPoet's Frage: (i) Pfade zu Modul Controller-Verzeichnisse können angegeben werden siehe zB: durch Anrufe an Front-Controller "12.11.2 Modul Controller spezifizieren Verzeichnisse" (Zend Framework Docs)

(ii) Wege zur Ansichten eingestellt werden können, unter Verwendung von Viewrenderer (Controller Aktion Helper) zB siehe: 'Beispiel 12.12. Auswählen eines anderen View-Skripts (Zend Framework-Dokumente)

Durch Herumspielen ist es möglich, die Standardpfade zu Views und Controllern zu ändern und somit Ihren Autoloader so zu starten, dass er normal läuft.

(ich habe nicht in die Art und Weise haben Autoloader funktioniert, aber es wäre sinnvoll, denn es einige Mapper System zu haben, diese Art von Problem zu lösen.)

1

ich diesen Brauch Action Helfer für das Problem gerade gebaut Sie beschreiben:

<?php 

class My_Controller_Action_Helper_GetModel extends Zend_Controller_Action_Helper_Abstract 
{ 
    /** 
    * @var Zend_Loader_PluginLoader 
    */ 
    protected $_loader; 

    /** 
    * Initialize plugin loader for models 
    * 
    * @return void 
    */ 
    public function __construct() 
    { 
    // Get all models across all modules 
    $front = Zend_Controller_Front::getInstance(); 
    $curModule = $front->getRequest()->getModuleName(); 

    // Get all module names, move default and current module to 
    // back of the list so their models get precedence 
    $modules = array_diff(
     array_keys($front->getDispatcher()->getControllerDirectory()), 
     array('default', $curModule) 
    ); 
    $modules[] = 'default'; 
    if ($curModule != 'default') { 
     $modules[] = $curModule; 
    } 

    // Generate namespaces and paths for plugin loader 
    $pluginPaths = array(); 
    foreach($modules as $module) { 
     $pluginPaths[ucwords($module)] = $front->getModuleDirectory($module) . '/models'; 
    } 

    // Load paths 
    $this->_loader = new Zend_Loader_PluginLoader($pluginPaths); 
    } 

    /** 
    * Load a model class and return an object instance 
    * 
    * @param string $model 
    * @return object 
    */ 
    public function getModel($model) 
    { 
    $class = $this->_loader->load($model); 
    return new $class; 
    } 

    /** 
    * Proxy to getModel() 
    * 
    * @param string $model 
    * @return object 
    */ 
    public function direct($model) 
    { 
    return $this->getModel($model); 
    } 
} 

Also in Ihrem Bootstrap.php:

Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper'); 

Und in jedem Ihrer Controller:

<?php 

class IndexController extends Zend_Controller_Action 
{ 
    public function indexAction() 
    { 
    $model = $this->_helper->getModel('SomeModel'); 
    } 
} 

Dies ermöglicht Ihnen den Zugriff auf Modelle in jedem Controller über alle Module hinweg.

0

<?php 
return array(
'modules' => array(
    'Application', 
    'DoctrineModule', 
    'DoctrineORMModule', 
    'Merchant', 
), 
'module_listener_options' => array(
    'config_glob_paths' => array(
     'config/autoload/{,*.}{global,local}.php', 
    ), 
    'module_paths' => array(
     './module', 
     '../vendor', 
//   'here we can load module' 
     'comomonmodule' 

    ), 
), 
); 
Verwandte Themen