簡體   English   中英

如何在Zend Framework中的不同模塊中使用相同的模型?

[英]How to Use Same Models in Different Modules in Zend Framework?

我正在一個現有項目中實施Zend Framework,該項目包括公共營銷區域,私有成員區域,管理站點和營銷活動管理站點。 目前,這些組織結構不佳,營銷區域的控制器腳本和成員區域都位於站點的根目錄下,然后是管理員的單獨文件夾和營銷活動站點的另一個文件夾。

在實現Zend框架時,我想創建能夠將控制器和視圖拆分為模塊(一個用於成員區域,一個用於公共營銷區域,一個用於管理站點,一個用於營銷活動管理站點)但我需要能夠將每個模塊指向同一個模型,因為所有三個組件都在同一個數據庫和同一個業務對象上工作。

但是,我無法在文檔中找到有關如何執行此操作的任何信息。 任何人都可以幫助解決如何執行此操作的鏈接或如何完成它的一些簡單說明?

我所做的是將公共類保存在模塊層次結構之外的“庫”目錄中。 然后設置我的INCLUDE_PATH以使用相應模塊的“models”目錄以及公共“library”目錄。

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

在我的bootstrap腳本中,我將“ application/library/ ”添加到INCLUDE_PATH 然后在每個控制器的init()函數中,我將該模塊的“ models/ ”目錄添加到INCLUDE_PATH

編輯: setControllerDirectory()setModuleDirectory()類的函數不會將相應的模型目錄添加到INCLUDE_PATH 無論如何,你必須自己做。 以下是如何執行此操作的一個示例:

$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()
    )
  )
);

您可以在引導程序中將“ library ”添加到路徑中,但是您無法在引導程序中為正確的模塊添加“ models ”目錄,因為模塊依賴於路由。 有些人在他們的控制器的init()方法中執行此操作,並且有些人為ActionController的preDispatch掛鈎編寫插件以設置INCLUDE_PATH

這也可以通過遵循Zend_Loader的命名約定來完成。 將模型文件保存在模塊文件夾下的models文件夾中。 將它們命名為Module_Models_ModelName並將它們保存在該模塊的models文件夾中的文件名ModelName.php中。 確保應用程序文件夾位於包含路徑中,並假設您使用Zend_Loader進行自動加載,然后您可以按類名引用模型。

這樣做的好處是可以將模型代碼與實際模塊分組。 這使模塊包含在單個文件夾結構中,這有助於鼓勵封裝。 如果您需要將模塊移植到另一個項目,這也將有助於將來。

我剛為你描述的問題構建了這個自定義Action Helper:

<?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);
  }
}

所以在你的Bootstrap.php中:

Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper');

在任何控制器中:

<?php

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

這將允許您訪問所有模塊中任何控制器中的模型。

<?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'   

    ),
),
);

我遇到了同樣的問題。 比爾的答案不適合我 - 因為我傾向於分割我的模塊,而不是“誰看到他們”,而是“他們做什么”。 例如,'論壇模塊'可能由管理員和公眾管理。 我正在嘗試擁有前端模塊,如管理員,成員,公共 - 但這些模塊然后使用其他模塊,如'forum / validatepost','forum / show users personal info'。 如果有人能夠闡明他們如何保護后端模塊免受公眾攻擊,那么這將是很方便的。 我猜ACL可能是關鍵,但它仍然讓我感到緊張的是由對象控制的訪問,而不是“文件系統/ .htaccess”等。

回答PHPoet的問題:(i)可以通過調用前端控制器來指定模塊控制器目錄的路徑:例如,參見:“12.11.2。指定模塊控制器目錄”(Zend Framework Docs)

(ii)可以使用ViewRenderer(Controller Action Helper)設置視圖的路徑,例如,參見:'例12.12。 選擇不同的視圖腳本'(Zend Framework Docs)

通過游戲可以改變視圖和控制器的默認路徑,從而釋放自動加載器以正常運行。

(我沒有研究自動加載器的工作方式,但它有一些映射器系統可以解決這類問題。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM