1

我同时使用 Zend 框架和 Django,它们都有自己的优点和缺点,但它们都是以自己的方式很好的框架。

我确实想创建一个高度模块化的 Web 应用程序,例如以下示例:

  • 模块:
    • 行政
      • 厘米
        • 文章
        • 部分
      • ...
        • ...
          • ...

我还希望所有模块都包含所有 confid 和模板文件。

最近几天我一直在寻找解决这个问题的方法,但是在模块设置中添加一个 omer 级别感觉不对。我确信这可以做到,但我应该这样做吗?我还在我的 zend 应用程序中包含了 Doctrine,这可能会给我的模块设置带来更多问题!

当我们谈论 Django 时,这很容易实现(在概念上很容易,而不是在实现时间或其他方面),并且是创建 Web 应用程序的好方法。但是 Django 的缺点之一是 web hosing 部分。有一些网络主机提供 Django 支持,但不是很多..

那么我想问题是什么最有价值;快速模块化开发与托管选项!

嗯,欢迎评论!

谢谢

4

2 回答 2

4

您可以在 ZF 中轻松实现子模块。假设您有目录结构,例如:

application/
  modules/
    admin/
      cms/
        controllers/
        views/
      controllers/
      views/

您可以在引导程序中注册这样的模块(子模块使用 _ 将子模块与主模块分开):

$frontController->setControllerDirectory(array(
    'default'   => APPLICATION_PATH . '/modules/default/controllers',
    'admin'     => APPLICATION_PATH . '/modules/admin/controllers',
    'admin_cms' => APPLICATION_PATH . '/modules/admin/cms/controllers'
));

问题在于它实际上会在 URL 中使用下划线而不是斜杠,例如:“admin_cms/conteroller/action”而不是“admin/cms/controller/action”。虽然这“有效”,但它并不漂亮。解决该问题的一种方法是为默认路由提供您自己的路由。由于默认的 Zend_Controller_Router_Route_Module几乎是正确的,你可以简单地从它扩展并添加想要的行为:

<?php

class App_Router_Route_Module extends Zend_Controller_Router_Route_Module
{
    public function __construct()
    {
        $frontController = Zend_Controller_Front::getInstance();
        $dispatcher = $frontController->getDispatcher();
        $request = $frontController->getRequest();
        parent::__construct(array(), $dispatcher, $request);
    }

    public function match($path)
    {
        // Get front controller instance
        $frontController = Zend_Controller_Front::getInstance();

        // Parse path parts
        $parts = explode('/', $path);

        // Get all registered modules
        $modules = $frontController->getControllerDirectory();

        // Check if we're in default module
        if (count($parts) == 0 || !isset($modules[$parts[0]]))
            array_unshift($parts, $frontController->getDefaultModule());

        // Module name
        $module = $parts[0];

        // While there are more parts to parse
        while (isset($parts[1])) {
            // Construct new module name
            $module .= '_' . $parts[1];

            // If module doesn't exist, stop processing
            if (!isset($modules[$module]))
                break;

            // Replace the parts with the new module name
            array_splice($parts, 0, 2, $module);
        }

        // Put path back together
        $path = implode('/', $parts);

        // Let Zend's module router deal with the rest
        return parent::match($path);
    }
}

在你的引导程序中:

$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('default', new App_Router_Route_Module);

它所做的就是只要找到一个模块就遍历路径,并透明地重写路径,以便默认的 Zend_Controller_Router_Route_Module 可以完成真正的工作。例如下面的路径:“/admin/cms/article/edit”将被转换成“/admin_cms/article/edit”,这使得ZF的“:module/:controller/:action”的标准约定变得神奇.

这允许您拥有带有独立模块的良好模块化结构,同时仍然使用漂亮的逻辑 URL。您要注意的一件事是,如果您使用 Zend_Navigation 并使用模块/控制器/操作参数指定导航项,您需要告诉 ZF 如何使用模块名称中的“/”而不是“_”正确构建 URL (默认情况下,ZF 在构建 URL 时使用 :module/:controller/:action 规范)。您可以通过实现自己的 Zend_Controller_Action_Helper_Url 来做到这一点,如下所示:

<?php

class App_Router_Helper_Url extends Zend_Controller_Action_Helper_Url
{
    public function url($urlOptions = array(), $name = null, $reset = false, $encode = false)
    {
        // Replace the _ with / in the module name
        $urlOptions['module'] = str_replace('_', '/', $urlOptions['module']);

        // Let the router do rest of the work
        return $this->getFrontController()->getRouter()->assemble($urlOptions, $name, $reset, $encode);
    }
}

在你的引导程序中:

Zend_Controller_Action_HelperBroker::addHelper(new App_Router_Helper_Url);

现在 Zend_Navigation 也可以很好地与您的子模块支持一起工作。

于 2009-10-28T09:22:51.643 回答
3

我(尽管是快乐的 ZF 用户)会选择 Django。在 ZF 中,“完全模块化”的应用程序是一种圣杯。创建自包含模块几乎是不可能的(或者至少不需要付出极大的努力),可以安装,例如“将此文件夹复制到您的模块目录中”:) 不确定 Django,但从我的角度来看,它更简单......

于 2009-10-28T11:43:09.633 回答