Search code examples
phpconfigurationzend-framework2configconfiguration-files

How to use the global.php/local.php configs in the getConfig() of a module in a Zend Framework 2 application?


In a ZF2 application I have some cofigs, that: 1. need to be different dependening on the environment; 2. are specific for a concrete module. I'm curently using it like here described:

global.php & local.php

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

Module class

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'],
                            ...
                        ));
                    },
                    ...
                )
            );
        }
        ...
    }
    ...
}

It's working fine, but I believe, that the module specific settings should be accessed over one central place in the module -- the getConfig() method of the Module class. Like this:

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'],
                            ...
                        ));
                    },
                    ...
                )
            );
        }
        ...
    }
    ...
}

The problem is, that I don't get, how to access the global.php/local.php configs in the getConfig() of a module. How can I do it?


Solution

  • You're not supposed to access other Modules setting in your Module#getConfig(). If you rely on other configuration, that CAN ONLY BE for service purposes. Ergo you'd rely on Module#getServiceConfig() and inside the factories you do have access to the ServiceManagerand access your configs with $serviceManager->get('config');. (see Sam's comment)

    The loading order of the configs is by default:

    1. /config/application.config.php, that is the initial config file; not for module configs; here is the filename pattern for the config files to load defined ('config_glob_paths' => array('config/autoload/{,*.}{global,local}.php')).
    2. {ModuleNamespace}\Module#getConfig() (e.g. Cache\Module#getConfig()), that by convention should load its /module/{ModuleNamespace}/config/module.config.php;
    3. /config/autoload/global.php, that should not contain any module specific configs (see below);
    4. /config/autoload/local.php, that contains environment specific settings also should not contain any module specific configs (see below); it should not versioned/deployed;
    5. /config/autoload/{ModuleNamespaceLowerCased}.local.php (e.g. cache.local.php), that contains only the module AND environment specific settings and should not be versioned/;

    For the Cache module above there can be following config files:

    • /module/Cache/config/module.config.php -- a complete set of module configs; loaded by Cache\Module#getConfig()
    • /module/Cache/config/cache.local.php.dist -- an example for /config/autoload/cache.local.php
    • /config/autoload/cache.local.php -- environment specific module configs

    The setting ttl can be accessed from any place, where one has access to the Service Locator. For example in factory methods of 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'],
                                ...
                            ));
                        },
                        ...
                    )
                );
            }
            ...
        }
        ...
    }
    

    For futher information about how configs are managed in ZF2 see Sam's answer and blog article.