我正在努力在一个现有的项目中实现Zend Framework,该项目有一个公共营销区,一个私人会员区,一个管理站点和一个营销活动管理站点。目前,这些都组织得很差,营销区域和成员区域的控制器脚本都在网站的根目录下,然后是一个单独的管理文件夹和另一个营销活动网站的文件夹。
在实现Zend框架时,我希望能够将控制器和视图拆分成模块(一个用于成员区域,一个用于公共营销区域,一个用于管理站点,一个用于营销活动管理站点),但我需要能够将每个模块指向相同的模型,因为所有三个组件都在相同的数据库和相同的业务对象上工作。
但是,我在文档中找不到任何关于如何做到这一点的信息。有没有人可以提供一个如何做到这一点的链接,或者一些关于如何完成它的简单说明?
发布于 2008-11-03 18:22:00
我所做的是将公共类放在模块层次结构之外的“库”目录中。然后将我的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/
. . .在我的引导脚本中,我会将"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。
发布于 2008-11-16 04:14:39
这也可以通过遵循Zend_Loader的命名约定来实现。将模型文件保存在其模块文件夹下的models文件夹中。将它们命名为Module_Models_ModelName,并将其保存在该模块的models文件夹中名为ModelName.php的文件中。确保应用程序文件夹在您的包含路径中,并且假设您正在使用Zend_Loader进行自动加载,那么您就可以通过它们的类名来引用模型。
这样做的好处是可以将您的模型代码与实际的模块分组在一起。这使模块包含在单个文件夹结构中,这有助于鼓励封装。如果您需要将模块移植到另一个项目,这在将来也会有所帮助。
发布于 2009-06-02 23:19:10
我刚刚为您描述的问题构建了这个自定义的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');
}
}这将允许您跨所有模块访问任何控制器中的模型。
https://stackoverflow.com/questions/259456
复制相似问题