开放的编程资料库

当前位置:我爱分享网 > PHP教程 > 正文

Zend Framework 中的模块引导程序:注意事项

我经常看到一些关于ZendFramework中模块引导程序的问题,并决定是时候写一篇关于它们的帖子了。

在ZendFramework1.8.0中,我们添加了Zend_Application,旨在(a)规范引导过程,以及(b)使其可重用。它的一个方面是允许引导各个应用程序模块——它们是控制器、视图和模型的离散集合。

我收到的关于模块引导程序的最常见问题是:

为什么所有模块引导程序都在每个请求上运行,而不仅仅是请求模块的引导程序?

为什么所有模块引导程序都在每个请求上运行,而不仅仅是请求模块的引导程序?

要回答这个问题,首先我需要提供一些背景知识。

当涉及到模块时,我们有三个典型的问题或需求:

  • 确保模块资源——模型、视图助手等——在应用程序的其他地方可用
  • 初始化模块特定的资源,例如路由、导航元素等。
  • 运行此模块特定的代码(选择特定布局、选择特定数据库适配器等)

Zend_Application回答了前两个问题。默认情况下,它会为所有公共资源(模型、表单、视图助手和过滤器、DbTable对象等)设置资源自动加载器,还允许您指定要在引导时加载的资源。

这就是事情变得有趣的地方。

ZFMVC请求的基本工作流程如下:

  1. 应用程序引导
  2. 路由
  3. 调度

Zend_Application只处理该列表中的第一项,引导。那时,我们不知道请求到底是什么——那是在路由过程中发生的。只有在路由之后我们才知道请求了哪些模块、控制器和操作。

那么,您的模块引导程序有什么意义呢?

引导是为了准备

如前所述,Zend_Application旨在引导您的应用程序。这意味着“准备好执行”。这个想法是按顺序获取所有依赖项,这样一旦您准备好路由和/或分派,应用程序可能需要的一切都已准备就绪。

当涉及到模块时,路由和调度之前您需要准备的各种东西包括:

  • 模块资源的自动加载支持。这样一来,如果您需要,应用程序中任何地方的代码都可以使用该模块的资源。示例包括访问视图助手、访问模型、访问表单等。默认情况下启用资源自动加载
  • 设置特定于模块的路由。你如何首先到达模块的控制器?它响应什么路线?提供此信息的时间是在引导过程中,路由发生之前。
  • 模块特定的导航元素。这通常与您的路由密切相关(大多数Zend_Navigation页面使用命名路由)。
  • 设置模块特定的插件。如果您的模块可能需要在路由/调度周期中启用某些功能,请设置插件并将它们附加到前端控制器。

最后一点是理解进行特定于模块的初始化的适当位置的关键——也就是说,只有在模块在路由期间匹配时才应该进行初始化和/或引导。

使用插件进行特定的初始化

重申一下:如果您的初始化任务只有在执行模块时才应该完成,请在前端控制器插件或actionhelper中完成。

如果在前端控制器插件中执行此操作,请在路由后随时执行这些初始化,因为这是您唯一知道模块是什么的时间。对于切换布局等一般任务,routeShutdown()dispatchLoopStartup()是正确的地方。只需将请求对象中的模块与您的模块进行比较,如果不匹配则提前退出。

class Foomodule_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        if ('foomodule' != $request->getModuleName()) {
            // If not in this module, return early
            return;
        }

        // Change layout
        Zend_Layout::getMvcInstance()->setLayout('foomodule');
    }
}

您的模块bootstrap将负责将此插件注册到前端控制器:

class Foomodule_Boootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initPlugins()
    {
        $bootstrap = $this->getApplication();
        $bootstrap->bootstrap('frontcontroller');
        $front = $bootstrap->getResource('frontcontroller');

        $front->registerPlugin(new Foomodule_Plugin_Layout());
    }
}

为了简单起见,并减少拥有大量插件的性能开销,您可能希望创建一个执行所有初始化的插件;Facade模式很适合在这里使用。

如果使用动作助手,想法是一样的—唯一的区别是您向动作助手代理注册,并且可能会在preDispatch()挂钩中进行匹配。

有没有更好的方法来做到这一点?

是的,可能有更好的方法来实现这一点。真正的问题是模块目前在ZF中实际上是二等公民。有一些想法浮出水面:

  • Kathryn的Active模块配置
  • Jeroen的Moduleconfig
  • Matthijs的ModuleConfig
  • Pádraic和Rob的模块配置器提案

对于2.0,我们将分析情况,看看我们是否可以想出办法让模块的一等公民成为ZF中的一等公民。我希望这将允许用户轻松地开始共享模块——这可以培养一种更像“插件”的方法来构建网站,并导致在经常需要的站点功能(例如博客、新闻、联系人等模块)上进行协作。).

与此同时,希望这篇文章有助于阐明模块配置当前的工作原理,并提供一些关于如何设置应用程序以利用模块特定资源和初始化的提示和技术。

更新

  • 2010-03-12:添加指向Paddy提案的链接
未经允许不得转载:我爱分享网 » Zend Framework 中的模块引导程序:注意事项

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏