首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Zend框架的不同模块中使用相同的模型?

如何在Zend框架的不同模块中使用相同的模型?
EN

Stack Overflow用户
提问于 2008-11-03 18:09:58
回答 5查看 11.6K关注 0票数 8

我正在努力在一个现有的项目中实现Zend Framework,该项目有一个公共营销区,一个私人会员区,一个管理站点和一个营销活动管理站点。目前,这些都组织得很差,营销区域和成员区域的控制器脚本都在网站的根目录下,然后是一个单独的管理文件夹和另一个营销活动网站的文件夹。

在实现Zend框架时,我希望能够将控制器和视图拆分成模块(一个用于成员区域,一个用于公共营销区域,一个用于管理站点,一个用于营销活动管理站点),但我需要能够将每个模块指向相同的模型,因为所有三个组件都在相同的数据库和相同的业务对象上工作。

但是,我在文档中找不到任何关于如何做到这一点的信息。有没有人可以提供一个如何做到这一点的链接,或者一些关于如何完成它的简单说明?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2008-11-03 18:22:00

我所做的是将公共类放在模块层次结构之外的“库”目录中。然后将我的INCLUDE_PATH设置为使用相应模块的"models“目录,外加公共的"library”目录。

代码语言:javascript
运行
复制
docroot/
    index.php
application/
    library/    <-- common classes go here
    default/
        controllers/
        models/
        views/
    members/
        controllers/
        models/
        views/
    admin/
        controllers/
        models/
        views/
. . .

在我的引导脚本中,我会将"application/library/“添加到INCLUDE_PATH中。然后,在每个控制器的init()函数中,我将该模块的"models/“目录添加到INCLUDE_PATH中。

编辑:像setControllerDirectory()setModuleDirectory()这样的函数不会将相应的模型目录添加到INCLUDE_PATH中。在任何情况下,你都必须自己做这件事。这里有一个如何做到这一点的例子:

代码语言:javascript
运行
复制
$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

票数 9
EN

Stack Overflow用户

发布于 2008-11-16 04:14:39

这也可以通过遵循Zend_Loader的命名约定来实现。将模型文件保存在其模块文件夹下的models文件夹中。将它们命名为Module_Models_ModelName,并将其保存在该模块的models文件夹中名为ModelName.php的文件中。确保应用程序文件夹在您的包含路径中,并且假设您正在使用Zend_Loader进行自动加载,那么您就可以通过它们的类名来引用模型。

这样做的好处是可以将您的模型代码与实际的模块分组在一起。这使模块包含在单个文件夹结构中,这有助于鼓励封装。如果您需要将模块移植到另一个项目,这在将来也会有所帮助。

票数 3
EN

Stack Overflow用户

发布于 2009-06-02 23:19:10

我刚刚为您描述的问题构建了这个自定义的Action Helper:

代码语言:javascript
运行
复制
<?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中:

代码语言:javascript
运行
复制
Zend_Controller_Action_HelperBroker::addPrefix('My_Controller_Action_Helper');

在你的任何控制器中:

代码语言:javascript
运行
复制
<?php

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

这将允许您跨所有模块访问任何控制器中的模型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/259456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档