从版本1.8.0开始,我们将Zend_Application添加到ZendFramework。该组件背后的目的是规范应用程序引导过程,并为其提供一个简化的、配置驱动的机制。
Zend_Application
与Zend_Application_Bootstrap
结合使用,正如您可能从其名称中猜到的那样,它真正完成了引导应用程序的大部分工作。它允许您利用pluginbootstrap资源,或将本地bootstrap资源定义为类方法。前者允许重用,后者用于特定于应用程序的初始化和配置。
此外,Zend_Application_Bootstrap
提供依赖跟踪(即,如果一个资源依赖于另一个资源,您可以确保先执行另一个资源),并充当已初始化资源的存储库。这意味着一旦资源被引导,您稍后可以从引导程序本身检索它。
工作原理
现在您已经知道它的作用了,让我们开始了解基础知识。
如果您使用ZendFramework提供的zf
命令行工具来生成您的项目(zfcreateproject
),您将立即获得引导程序和默认配置的大门。这包括树中的以下文件:
application/ |-- Bootstrap.php | `-- configs/ | | `-- application.ini
Bootstrap.php
文件将包含扩展Zend_Application_Bootstrap_Bootstrap
的类Bootstrap
;这个类一开始是空的。application.ini
文件将包含以下内容:
[production] phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0 includePaths.library = APPLICATION_PATH "/../library" bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap" appnamespace = "Application" resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers" resources.frontController.params.displayExceptions = 0 [staging : production] [testing : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 [development : production] phpSettings.display_startup_errors = 1 phpSettings.display_errors = 1 resources.frontController.params.displayExceptions = 1
Zend_Application
分三个阶段运行。首先,它初始化PHP环境,使用您的配置中的INI设置(如果提供),并设置include_path
和自动加载。其次,它初始化并执行引导程序类。最后,它会“运行”应用程序(通过调用引导程序的run()
方法)。
配置设置
我们在上面的列表中看到的是一组:
- PHP初始化设置(这里表示是否显示错误)
include_path
settings- 表示名称和错误的设置引导类的位置
- 应用程序资源设置
phpSettings
键接受任何php.ini
键作为子键,这些键/值对将传递给ini_set
。当您需要确保进行特定的INI设置时,特别是当您希望它们根据环境而变化时,这会很有用。(在上面的示例中,display_errors
在测试和开发中启用,但在其他情况下禁用。)
当涉及到include_path
和自动加载时,最常被问到的问题可能是“如何将ZF以外的代码的命名空间前缀添加到自动加载器?”这可以在配置文件中使用autoloaderNamespaces
键轻松完成,并为其附加命名空间前缀:
autoloaderNamespaces[] = "Phly_"
关于引导程序类和文件位置,通常使用默认值即可。然而,如果你想指定一个自定义名称——例如,提供一个类前缀——或者如果你的默认模块在一个子目录中,你不能通过bootstrap.class指定
和Zend_Application
boostrap.path
设置:
bootstrap.class = "Application_Bootstrap" bootstrap.path = APPLICATION_PATH "/modules/application/Bootstrap.php"
Bootstrap资源入门
现在我们终于到了真正的乐趣所在:引导程序资源本身。
是的,我知道我在掩饰“appnamespace”设置;我会在其他时间介绍。
Bootstrap资源可能是以下两种情况之一:
- 以
_init
为前缀的bootstrap类中的一个受保护方法;例如,protectedfunction_initFoo()
- Aclassimplementing
Zend_Application_Resource_Resource
在前一种情况下,_init*()
方法,每个方法都会在每个请求中执行。在后者中,只有您在配置中指定的那些才会被执行,允许您有选择地选择将使用各种随附的资源插件(或您自己编写的插件!)。
在默认配置的情况下,只会使用“frontcontroller”资源插件,对应于Zend_Application_Resource_Frontcontroller
。从即将发布的1.10版本开始,您还可以从以下附加资源插件中进行选择:
- Cachemanager
- Db
- Dojo
- Layout
- Locale
- Log
- 邮件
- 模块
- Multidb
- 导航
- 路由器
- 会话
- 查看
which>翻译
每个都有自己的配置选项,记录在手册中。
编写资源方法
编写您自己的资源方法很简单:您只需创建方法,然后做一些工作。然后您可以选择返回一个值;如果这样做,它将存储在引导程序中,以便您以后可以检索它。例如:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initRegistry() { $registry = new Zend_Registry(); return $registry; } }
如果我们想稍后检索注册表,我们可以使用引导程序的getResource()
方法:
$registry = $bootstrap->getResource('Registry');
请注意,我们传递的方法名称减去_init
前缀;这个“短名称”是资源在引导程序中的引用方式,以及您稍后将如何引用它。
现在,假设您有一个资源依赖于您的“Registry”资源;例如,假设您想要创建一个Zend_Currency
对象,并将它传递给注册表。Zend_Application_Bootstrap
就是为处理这种情况而设计的,并建立了一些强大的依赖跟踪(事实上,这就是初始化方法受到保护的原因;它防止它们被直接调用)。只需使用要初始化的资源名称调用bootstrap()
方法。此外,getResource()
方法可用于检索为该资源注册的值。例如:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initCurrency() { $this->bootstrap('Registry'); $registry = $this->getResource('Registry'); $currency = new Zend_Currency('$'); $registry['Zend_Currency'] = $currency; return $currency; } protected function _initRegistry() { $registry = new Zend_Registry(); return $registry; } }
接下来会发生什么:
Zend_Application
将调用不带参数的bootstrap()
,它首先循环遍历内部资源方法,然后是任何已配置的资源插件。- bootstrap将执行
_initCurrency()
方法 - 它看到
bootstrap()
调用,并执行它 bootstrap()
调用执行_initRegistry()
方法,在完成时在内部存储一个Zend_Registry
实例(从该方法返回)_initCurrency()
的执行恢复,从getResource()
调用开始;这将返回存储在引导程序中该键下的Zend_Registry
实例。_initCurrency()
的执行完成,并且引导程序存储返回的Zend_Currency
实例。bootstrap()
方法然后尝试调用_initRegistry()
方法,但注意到它已经执行,然后继续执行资源插件。
正如您现在所看到的,引导程序功能非常灵活和强大,并且立即提供了许多开箱即用的好处。
下次见…
此时,您应该已经足够开始编写您自己的引导程序初始化资源了。在接下来的几周内,我将发布有关如何构建可重用资源插件的博客,并讨论引导程序如何适合模块化应用程序。