菜菜鳥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



未完待續,謝謝......

相關文章
相關標籤/搜索