菜菜鸟Zend Framework 2 不彻底学习涂鸦(十五)-- 高级配置技巧

高级配置技巧

Zend Framework 2应用程序的配置发生在如下几个步骤: php

  • 初始配置经过Application实例和使用ModuleManager和ServiceManager的种子。在这篇教程中,咱们称这个配置:系统配置(System Configuration)
  • 当有模块调用时ModuleManager的ConfigListener集合配置和合并它。在这篇教程中,咱们称这个配置:应用配置(Application Configuration)
  • 一旦从全部模块中聚合配置,ConfigListener还将在指定目录中合并全局应用配置(典型目录是config/autoload/)

在这篇教程中,咱们将着眼于恰当的顺序以及如何约束它们。 html

1、系统配置(System Configuration

开始模块装载,咱们必须告诉Application实例有关有效的模块以及它们在哪里,随意提供一些信息给默认的模块监听器(例如:应用配置在哪里,以及什么文件被装载;是否缓存合并配置放在哪里,等等),随意ServiceManager播种。在本教程中咱们称这个配置为系统配置(System Configuration) web

当使用应用程序骨架(或者应用程序框架)时,系统配置(System Configuration)默认在config/application.config.php里。看上去相似下面的代码: shell

<?php
return array(
    // This should be an array of module namespaces used in the application.
    'modules' => array(
        'Application',
    ),

    // These are various options for the listeners attached to the ModuleManager
    'module_listener_options' => array(
        // This should be an array of paths in which modules reside.
        // If a string key is provided, the listener will consider that a module
        // namespace, the value of that key the specific path to that module's
        // Module class.
        'module_paths' => array(
            './module',
            './vendor',
        ),

        // An array of paths from which to glob configuration files after
        // modules are loaded. These effectively overide configuration
        // provided by modules themselves. Paths may use GLOB_BRACE notation.
        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),

        // Whether or not to enable a configuration cache.
        // If enabled, the merged configuration will be cached and used in
        // subsequent requests.
        //'config_cache_enabled' => $booleanValue,

        // The key used to create the configuration cache file name.
        //'config_cache_key' => $stringKey,

        // Whether or not to enable a module class map cache.
        // If enabled, creates a module class map cache which will be used
        // by in future requests, to reduce the autoloading process.
        //'module_map_cache_enabled' => $booleanValue,

        // The key used to create the class map cache file name.
        //'module_map_cache_key' => $stringKey,

        // The path in which to cache merged configuration.
        //'cache_dir' => $stringPath,

        // Whether or not to enable modules dependency checking.
        // Enabled by default, prevents usage of modules that depend on other modules
        // that weren't loaded.
        // 'check_dependencies' => true,
    ),

    // Used to create an own service manager. May contain one or more child arrays.
    //'service_listener_options' => array(
    //     array(
    //         'service_manager' => $stringServiceManagerName,
    //         'config_key'      => $stringConfigKey,
    //         'interface'       => $stringOptionalInterface,
    //         'method'          => $stringRequiredMethodName,
    //     ),
    // )

   // Initial configuration with which to seed the ServiceManager.
   // Should be compatible with Zend\ServiceManager\Config.
   // 'service_manager' => array(),
);

系统配置有关MVC的点点滴滴在在你系统以前运行并准备好了。配置一般是简报而且至关小巧的。 数据库

另外,当即使用的系统配置,而且没有合并任何其它的配置-也就是说它不能被其它模块覆盖。 apache

这引导咱们到咱们第一个技巧:如何提供特定环境下的系统配置? 编程

2、特定环境系统配置

当你要改变一整套基于环境的模块时会发生什么?或者若是配置缓存基于环境被启用会发生什么? 数组

就是这个缘由咱们在应用程序框架中提供的默认系统配置是使用PHP的;使用PHP来支持的意思是说经过编程来控制它。 缓存

做为一个例子,让咱们作如下的要求: 闭包

  • 咱们要求只在开发阶段使用ZendDeveloperTools模块
  • 咱们要求只在生产中有配置缓存

要实现以上的要求,咱们在咱们的Web Server的配置中设置一个环境变量,在Apache中设置APP_ENV,要么在你系统级的apache.conf文件,要么在http.conf文件中输入相似如下命令,或者在你的虚拟主机中定义,也能够输入到.htaccess文件中

SetEnv "APP_ENV" "development"

对于其它的web server,查阅web server文档来肯定如何设置环境变量

为了简化问题,咱们假定环境是“生产”若是没有环境变量存在。

咱们按照如下的代码修改config/application.config.php

<?php
$env = getenv('APP_ENV') ?: 'production';

// Use the $env value to determine which modules to load
$modules = array(
    'Application',
);
if ($env == 'development') {
    $modules[] = 'ZendDeveloperTools';
}

return array(
    'modules' => $modules,

    'module_listener_options' => array(
        'module_paths' => array(
            './module',
            './vendor',
        ),

        'config_glob_paths' => array(
            'config/autoload/{,*.}{global,local}.php',
        ),

        // Use the $env value to determine the state of the flag
        'config_cache_enabled' => ($env == 'production'),

        'config_cache_key' => 'app_config',

        // Use the $env value to determine the state of the flag
        'module_map_cache_enabled' => ($env == 'production'),

        'module_map_cache_key' => 'module_map',

        'cache_dir' => 'data/config/',

        // Use the $env value to determine the state of the flag
        'check_dependencies' => ($env != 'production'),
    ),
);

这种方法给你带来了改变系统级设置的灵活性。

可是,如何在基于环境的状况下修改应用程序特定的设置(不是系统配置)?

3、特定环境应用程序配置

有些时候你想要修改应用程序配置来调用一些东西,例如数据库适配器,log写入,缓存适配器以及更多机基于环境的东西。这些在服务管理器中具备表明性的托管可能在模块中被定义。你能够经过Zend\ModuleManager\Listener\ConfigListener在应用级别中重写它们,通过一个在系统配置(System Configuration)中指定的全局路径 - 在上例中的module_listener_options.config_glob_paths关键字。

它的默认值是config/autoload/{,*.}{global,local}.php。这个意思是说它会在config/autoload目录中按照如下的顺序寻找应用程序配置(Application Configuration)

  • global.php
  • *.global.php
  • local.php
  • *.local.php

这容许你在“全局”配置文件中定义应用程序级别的默认值,而后提交到版本控制系统中,特定环境下在“本地”配置文件中重写那些你会忽略版本控制的值。

这是一个很是好的开发解决方案,它容许你指定交替的配置,针对你的开发环境不用担忧意外的部署。

然而,若是你有不少环境 - 例如一个“测试”或者“展示”环境 - 它们每一个都有本身的特殊的重写?

再说一次,使用应用程序环境变量。咱们能够稍稍的改变如下系统配置中的全局路径:

'config_glob_paths' => array(
    sprintf('config/autoload/{,*.}{global,%s,local}.php', $env)
),
以上代码容许你为每一个环境额外的定义应用程序配置文件;此外,只有当相应的环境被侦测到,这些配置才会被调用!

做为一个例子,考虑一下如下的配置文件结构树:

config/
    autoload/
        global.php
        local.php
        users.development.php
        users.testing.php
        users.local.php
若是$env是testing,如下的文件将按照顺序被合并:
global.php
users.testing.php
local.php
users.local.php
注意:users.development.php没有被调用 - 由于它没有匹配全局模式!

此外,因为按照顺序调用,你能够预测哪些值会覆盖其它的值,让你能够在后来的调试中有选择性的覆盖。

注意:

在config/autoload/目录下的文件在模块配置以后被合并,具体信息见下个段落。咱们有详细的说明,然而,设定应用程序配置(Application Configuration)的全局路径是在系统配置(System Configuration)中的(config/application.config.php)

4、模块配置

模块的职责之一是为应用程序提供它们本身的配置。模块有两个通常的机制来实现这个。

首先,要么经过Zend\ModuleManager\Feature\ConfigProviderInterface实现和/或经过getConfig()方法返回模块的配置。默认,推荐使用getConfig()方法:

public function getConfig()
{
    return include __DIR__ . '/config/module.config.php';
}

module.config.php返回一个PHP数组。

第二,模块可以实现许多接口和/或与指定的服务管理器或插件管理器配置有关的方法。例如:

接口名称 方法名称
ControllerPluginProviderInterface
getControllerPluginConfig()
ControllerProviderInterface
getControllerConfig()
FilterProviderInterface
getFilterConfig()
FormElementProviderInterface
getFormElementConfig()
HydratorProviderInterface
getHydratorConfig()
InputFilterProviderInterface
getInputFilterConfig()
RouteProviderInterface
getRouteConfig()
SerializerProviderInterface
getSerializerConfig()
ServiceProviderInterface
getServiceConfig()
ValidatorProviderInterface
getValidatorConfig()
ViewHelperProviderInterface
getViewHelperConfig()

全部的接口列表都在Zend\ModuleManager\Feature命名空间中,每一个都为服务管理器返回一个配置数组,在“默认服务管理”中有提到。

考虑到你可能会在模块配置文件中含有服务配置,哪个优先?

合并的顺序是:

  • getConfig()返回的配置
  • 在模块类中经过各类服务配置方法返回的配置

换句话说,你各类服务配置方法优先。另外特别注意:从方法中返回的配置不会被缓存。缘由是它不是常用闭包或者工厂实例从你的模块类返回配置 - 不能可靠的缓存配置。

注意:

当你须要定义闭包或者为工厂模式定义回调接口,抽象工厂和初始化时使用各类服务配置方法,这预防了缓存问题,同时也容许你使用其它格式写你本身的配置文件。

5、合并配置工做流程

在结束本教程以前,让咱们回顾一下如何以及什么时候定义以及合并配置。

系统配置(System Configuration) - 在config/application.config.php中定义 - 不会合并 - 容许以编程方式操做,容许:

  • 在计算值的基础上改变标记
  • 在计算值的基础上改变配置全局路径
  • 配置被传递给Application接口,而后ModuleManager按照顺序初始化系统

应用程序配置(Application Configuration) - ModuleManager按照定义的顺序循环访问每一个模块类

系统配置(System Configuration)中 - 定义在模块类中的服务配置是聚合 - 经过Module::getConfig()返回的配置是聚合

  • 服务配置(Service Configuration)config_glob_paths设置中发现的文件会被合并,合并的顺序是根据它们在全局路径中的顺序。
  • 合并后的配置最终被传递给ServiceManager



未完待续,谢谢......

相关文章
相关标签/搜索