【问题标题】:How to use the global.php/local.php configs in the getConfig() of a module in a Zend Framework 2 application?如何在 Zend Framework 2 应用程序的模块的 getConfig() 中使用 global.php/local.php 配置?
【发布时间】:2013-04-05 11:18:02
【问题描述】:

在 ZF2 应用程序中,我有一些配置,即: 1. 需要根据环境而有所不同; 2. 特定于具体模块。我正在像here 描述的那样使用它:

global.php & local.php

return array(
    ...
    'modules' => array(
        'Cache' => array(
            'ttl' => 1, // 1 second
        )
    )
    ...
);

模块类

Module {
    ...
    public function getServiceConfig() {
        try {
            return array (
                'factories' => array(
                    'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
                        return new MemcachedOptions(array(
                            'ttl'           => $this->getConfig()['modules']['Cache']['ttl'],
                            ...
                        ));
                    },
                    ...
                )
            );
        }
        ...
    }
    ...
}

它工作得很好,但我相信,应该通过模块中的一个中心位置访问模块特定设置——Module 类的getConfig() 方法。像这样:

class Module {

    public function getConfig() {
        $moduleConfig = include __DIR__ . '/config/module.config.php';
        $application = $this->getApplicationSomehow(); // <-- how?
        $applicationModuleConfig = $application->getConfig()['modules'][__NAMESPACE__];
        $config = array_merge($moduleConfig, $applicationModuleConfig);
        return $config;
    }
    ...
    public function getServiceConfig() {
        try {
            return array (
                'factories' => array(
                    'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
                        return new MemcachedOptions(array(
                            'ttl'            => $serviceManager->get('Config')['modules']['Cache']['ttl'],
                            ...
                        ));
                    },
                    ...
                )
            );
        }
        ...
    }
    ...
}

问题是,我不明白如何访问模块的getConfig() 中的 global.php/local.php 配置。我该怎么做?

【问题讨论】:

    标签: configuration zend-framework2 config configuration-files


    【解决方案1】:

    每个加载的模块的每个配置都将合并到一个配置中。也就是说,这将是:

    $serviceManager->get('config');
    

    (global|local).config.php 背后的原因仅仅是为了使用目的。全局配置文件应始终部署。但是,本地配置文件只能部署为可分发文件,别名为 local.config.php.dist

    不会加载发行版,无论它们在哪里。然而 ZF2 的常见概念是将可分发文件复制到 ZF2 应用程序的 /config/autoload 目录中,并将它们重命名为 local.config.php

    一个例子:

    // YourModule/config/module.config.php
    return array(
        'key' => 1337
    );
    
    // YourModule/config/local.yourmodule.php.dist
    return array(
        'key' => 7331
    );
    

    现在,当您发布/部署应用程序时,将仅使用 module.config.php。如果有人想更改您模块的配置,他们将永远不会触摸module.config.php,因为当您的模块更新时,此文件会不断被覆盖。

    但是人们可以做的就是复制:

    YourModule/config/local.yourmodule.php.dist
    to
    /config/autoload/local.yourmodule.php
    

    并更改此本地配置中的配置值。

    理解:

    • 您应该始终尽可能为实时场景配置您的模块。
    • 如果您有特定于环境的需求,请使用本地配置覆盖此配置
    • 本地配置永远不会自动部署,这是一项需要从环境本身内部完成的手动任务

    希望这更清楚一点

    最终:

    • 为实时场景配置您的模块
    • 在您的开发机器上创建一个/config/autoload/mymodule.local.php 并用它的开发价值覆盖您的ttl

    加载顺序:

    我完全忘记的最后一个有趣的部分是配置文件的加载顺序。由于所有文件都已合并,因此请务必注意!

    • 首先加载的是/config/application.config.php
    • 第二个加载将是每个模块/modules/{module}/config/module.config.php *
    • 最后但并非最不重要的一点是,将加载可自动加载的文件/config/autoload/{filename}.php

    asterix其实调用的是NOTmodule.config.php,而是Module-classes配置函数。主要是:

    如果我对this part of the ConfigListener的理解正确,那么getConfig()将首先被调用,所有的专用{feature}ProviderInterfaces将覆盖getConfig()的数据,但不要认为这是理所当然的,它需要检查!

    【讨论】:

    • 好吧,我想,我明白了。 /module/Cache/config 中的local.%module%.php.distlocal.%module%.php 的示例)和module.config.php(默认设置)和/config/autoload 中的local.%module%.php(当前环境的实际设置)。 local.%module%.php 文件“自动”(魔术?)合并到 /config/autoload/local.php 并具有比 module.config.php 更高的优先级。 1. 我理解对了吗? 2. 钥匙呢?如果local.%module%.php文件直接合并到local.php,如何避免冲突? 3. 我可以/应该如何访问设置?
    • 在 Sam:非常感谢您的详细回答和更新。抱歉,我还是不明白,如何加载/autoload/local.{modulename}.php 文件。我为我的模块Cache 创建了/autoload/local.cache.php,但它没有加载。您能否发布一个基本示例,如何为模块MyModule 设置设置mysetting(在模块和应用程序配置文件夹中的所有可能相关文件中)以及如何从模块类访问此设置?
    • @Sam 到“如果我正确理解this part of the ConfigListener [...]”:我刚刚调试了一个模块,只是在它的每个配置方法中设置了一个断点(这个模块只实现了三个配置接口)。加载顺序为:getAutoloaderConfig()getConfig()getServiceConfig()
    • @automatix 我知道,就在今天我从这里写了一篇关于我的发现的博客;)samminds.com/2013/04/understanding-zf2-configuration
    • 您不应该访问Module#getConfig() 中的其他模块设置。如果您依赖其他配置,则只能用于服务目的。因此,您将依赖 Module#getServiceConfig() 并且在工厂内部您可以访问 ServiceManager
    【解决方案2】:

    您不应该访问Module#getConfig() 中的其他模块设置。如果您依赖其他配置,则只能用于服务目的。因此,您将依赖 Module#getServiceConfig(),并且在工厂内部您可以访问 ServiceManager 并使用 $serviceManager-&gt;get('config'); 访问您的配置。(参见 Sam 的 comment

    配置的加载顺序是默认的:

    1. /config/application.config.php,即初始配置文件;不适用于模块配置;这是要加载的配置文件的文件名模式('config_glob_paths' =&gt; array('config/autoload/{,*.}{global,local}.php'))。
    2. {ModuleNamespace}\Module#getConfig()(例如Cache\Module#getConfig()),按照惯例应该加载它的/module/{ModuleNamespace}/config/module.config.php
    3. /config/autoload/global.php,不应包含任何特定于模块的配置(见下文);
    4. /config/autoload/local.php,包含 环境特定 设置也不应包含任何模块特定配置(见下文);不应对其进行版本控制/部署;
    5. /config/autoload/{ModuleNamespaceLowerCased}.local.php(例如cache.local.php),仅包含模块和环境特定设置,不应进行版本控制/;

    对于上面的Cache 模块,可以有以下配置文件:

    • /module/Cache/config/module.config.php -- 一套完整的模块配置;由Cache\Module#getConfig()加载
    • /module/Cache/config/cache.local.php.dist——/config/autoload/cache.local.php 的示例
    • /config/autoload/cache.local.php -- 环境特定的模块配置

    设置ttl 可以从任何可以访问服务定位器的地方访问。例如在Cache\Module#getServiceConfig()的工厂方法中

    class Module {
    
        public function getConfig() {
            $moduleConfig = include __DIR__ . '/config/module.config.php';
            $application = $this->getApplicationSomehow(); // <-- how?
            $applicationModuleConfig = $application->getConfig()['modules'][__NAMESPACE__];
            $config = array_merge($moduleConfig, $applicationModuleConfig);
            return $config;
        }
        ...
        public function getServiceConfig() {
            try {
                return array (
                    'factories' => array(
                        'Zend\Cache\Adapter\MemcachedOptions' => function ($serviceManager) {
                            return new MemcachedOptions(array(
                                'ttl'            => $serviceManager->get('Config')['ttl'],
                                ...
                            ));
                        },
                        ...
                    )
                );
            }
            ...
        }
        ...
    }
    

    有关如何在 ZF2 中管理配置的更多信息,请参阅 Sam 的 answerblog article

    【讨论】:

    • 为什么您不接受@sam 回答作为您问题的有效答案?
    • 这是一篇非常好的理论文章(+1),但它并没有直接给我问题的答案。无论如何,它帮助我理解配置如何工作并找到答案。我在这里发布并接受/标记为“有效答案”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多