A free and open-source book on ZF3 for beginners


3.8. Application Configuration

Most of Zend Framework components which are used in your website, require configuration (fine-tuning). For example, in the configuration file you define database connection credentials, specify which modules are present in your application, and, optionally, provide some custom parameters specific to your application.

You can define the configuration parameters at two levels: either at the application level, or at the module level. At the application level you typically define parameters which control the whole app and are common to all modules of your application. At the module level, you define parameters which affect only this module.

Some PHP frameworks prefer conventions over configuration concept, where most of your parameters are hard-coded and do not require configuration. This makes it faster to develop the application, but makes it less customizable. In Zend Framework 3, the configuration over conventions concept is used, so you can customize any aspect of your application, but have to spend some time for learning how to do that.

3.8.1. Application-Level Config Files

The APP_DIR/config subdirectory contains application-wide configuration files. Let's look at this subdirectory in more details (figure 3.4).

Figure 3.4. Configuration files Figure 3.4. Configuration files

The APP_DIR/config/application.config.php file is the main configuration file. It is used by the application on start up for determining which application modules should be loaded and which services to create by default.

Below, the content of application.config.php file is presented. You can see that the configuration file is just a usual PHP nested associative array, and each component may have a specific key in that array. You can provide inline comments for the array keys to make it easier for others to understand what each key means.

By convention, key names should be in lower case, and if the key name consists of several words, the words should be separated by the underscore symbol ('_').

return [
    // Retrieve list of modules used in this application.
    'modules' => require __DIR__ . '/modules.config.php',

    // These are various options for the listeners attached to the ModuleManager
    'module_listener_options' => [
        // 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' => [
            './module',
            './vendor',
        ],

        // An array of paths from which to glob configuration files after
        // modules are loaded. These effectively override configuration
        // provided by modules themselves. Paths may use GLOB_BRACE notation.
        'config_glob_paths' => [
            realpath(__DIR__) . '/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' => true,

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

        // 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' => true,

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

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

        // 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' => [
    //     [
    //         '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' => [],
];

In line 3 we have the modules key defining which modules will be loaded on start up. You can see that the module names are stored inside of another config file modules.config.php, which lists all modules present in your website.

In line 11, there is the module_paths key which tells ZF3 about directories where to look for source files belonging to modules. Application modules that you develop are located under APP_DIR/module directory, and third-party modules may be located inside the APP_DIR/vendor directory.

And in line 19 we have the config_glob_paths key, which tells ZF3 where to look for extra config files. You see that files from APP_DIR/config/autoload which have global.php or local.php suffix, are automatically loaded.

Summing up, you typically use the main application.config.php file for storing the information about which modules should be loaded into your app and where they are located and how they are loaded (for example, you can control caching options here). In this file you can also tune the service manager. It is not recommended to add more keys in this file. For that purpose it is better to use autoload/global.php file.

And let's also look inside the modules.config.php file. Currently, you have the following modules installed in your website:

return [
    'Zend\Session',
    'Zend\Mvc\Plugin\Prg',
    'Zend\Mvc\Plugin\Identity',
    'Zend\Mvc\Plugin\FlashMessenger',
    'Zend\Mvc\Plugin\FilePrg',
    'Zend\Form',
    'Zend\Router',
    'Zend\Validator',
    'Application',
];

The Application module is a module containing your app's files. All other modules listed are Zend Framework components.

In ZF3, a special Composer plugin called component installer was introduced. If you remember, in the chapter Zend Skeleton Application, we answered several yes/no questions of the installer, determining which components to install. And the installer injected those components' module names here, in modules.config.php

3.8.2. Application-Level Extra Config Files

"Extra" config files, APP_DIR/config/autoload/global.php and APP_DIR/config/autoload/local.php files define application-wide environment-agnostic and environment-dependent parameters, respectively. These config files are automatically loaded and recursively merged with the module-provided config files, that's why their directory is named autoload.

Having different config files in APP_DIR/config/autoload directory, you might have been confused about which parameters should be put into each one. Here are some hints:

Because the autoload/local.php file contains environment-specific parameters, in version control system you store its "distribution template" local.php.dist. Each developer in your team then renames the local.php.dist file into local.php and enters his own parameters. This local.php file should not be stored under version control, because it may contain sensitive information like database credentials (username and password), and you might want that other people do not see these.

3.8.3. Application-Level Development Config File

The application-level development configuration file (APP_DIR/config/development.config.php) presents only when you enable the development mode. If you remember, we enabled the development mode earlier in the Zend Skeleton Application chapter.

You enable the development mode with the following command:

php composer.phar development-enable

The development.config.php file is merged with the main application.config.php file. This allows you to override some parameters. For example, you can:

If you disable the development mode, the development.config.php file will be removed. So, you should not store this file under the version control. Instead, store its distribution version, development.config.php.dist under version control.

3.8.4. Application-Level Extra Development Config Files

The application-level extra development configuration file (APP_DIR/config/autoload/development.local.php) presents only when you enable the development mode.

The development.local.php file is merged with other module-level config files. This allows you to override some module-specific parameters used in development environment only.

If you disable the development mode, the development.local.php file will be removed. So, you should not store this file under the version control. Instead, store its distribution version, development.local.php.dist under version control.

3.8.5. Module-Level Config Files

In figure 3.4, you could see that the Application module shipped with your application has the module.config.php file, in which you put your module-specific parameters. Let's look at module.config.php file of the Application module:

<?php
namespace Application;

use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;

return [
    'router' => [
        'routes' => [
            'home' => [
                'type' => Literal::class,
                'options' => [
                    'route'    => '/',
                    'defaults' => [
                        'controller' => Controller\IndexController::class,
                        'action'     => 'index',
                    ],
                ],
            ],
            'application' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/application[/:action]',
                    'defaults' => [
                        'controller'    => Controller\IndexController::class,
                        'action'        => 'index',
                    ],
                ],
            ],
        ],
    ],
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => InvokableFactory::class,
        ],
    ],
    'view_manager' => [
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => [
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ],
        'template_path_stack' => [
            __DIR__ . '/../view',
        ],
    ],
];

In this file, you register the module's controllers, put information about routing rules for mapping URLs to your controllers, register controller plugins, and also register view templates and view helpers (we will learn more about these terms in this chapter and in the next chapters).

3.8.6. Combining the Configuration Files

When an application is being created, module-provided configuration files and extra configuration files from APP_DIR/config/autoload directory are being merged into one big nested array, so every configuration parameter becomes available to any piece of the website. So, potentially, you are able to override some parameters specified by the modules.

You might also have seen the "combined" config file when installing PHP, where there is the main php.ini file and several extra config files, which are included into the main one. Such a separation makes your application configuration fine-grained and flexible, because you don't have to put all your params to a single file and edit it each time you need to change something.

The configuration files are loaded in the following order:


Top