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.
The APP_DIR/config subdirectory contains application-wide configuration files. Let's look at this subdirectory in more details (figure 3.4).
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
"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:
You use the autoload/global.php file for storing parameters which do not depend on the concrete machine environment. For example, here you can store parameters which override the default parameters of some module. Do not store sensitive information (like database credentials) here, for that purpose it's better to use autoload/local.php.
You use the autoload/local.php file for storing parameters specific to the
concrete environment. For example, here you can store your database credentials.
Each developer usually has a local database when developing and testing the website.
The developer thus will edit the local.php file and enter his own database credentials here.
When you install your site to the production server, you will edit the local.php
file and enter
the credentials for the "live" database here.
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.
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.
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.
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).
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:
The main application.config.php file is loaded first. It is used to initialize the service manager and load application modules. The data loaded from this config is stored alone and not merged with other config files.
Configuration files for each application module are loaded and merged. Modules are loaded in the same order as they are listed in the application.config.php file. If two modules store (either intentionally, or by mistake) parameters in the similar-named keys, these parameters may be overwritten.
Extra config files from the APP_DIR/config/autoload folder are loaded and merged into a single array. Then this array is merged with the module config array produced on the previous stage, when loading the module configuration. Application-wide configuration has higher priority than the module configuration, so you can override module keys here, if you wish.