diff --git a/cookbook/configuration/configuration_organization.rst b/cookbook/configuration/configuration_organization.rst new file mode 100644 index 00000000000..52c5c0f0d4a --- /dev/null +++ b/cookbook/configuration/configuration_organization.rst @@ -0,0 +1,363 @@ +.. index:: + single: Configuration + +How to Organize Configuration Files +=================================== + +The default Symfony2 Standard Edition defines three +:doc:`execution environments ` called +``dev``, ``prod`` and ``test``. An environment simply represents a way to +execute the same codebase with different configurations. + +In order to select the configuration file to load for each environment, Symfony +executes the ``registerContainerConfiguration()`` method of the ``AppKernel`` +class:: + + // app/AppKernel.php + use Symfony\Component\HttpKernel\Kernel; + use Symfony\Component\Config\Loader\LoaderInterface; + + class AppKernel extends Kernel + { + // ... + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); + } + } + +This method loads the ``app/config/config_dev.yml`` file for the ``dev`` +environment and so on. In turn, this file loads the common configuration file +located at ``app/config/config.yml``. Therefore, the configuration files of the +default Symfony Standard Edition follow this structure: + +.. code-block:: text + + / + ├─ app/ + │ └─ config/ + │ ├─ config.yml + │ ├─ config_dev.yml + │ ├─ config_prod.yml + │ ├─ config_test.yml + │ ├─ parameters.yml + │ ├─ parameters.yml.dist + │ ├─ routing.yml + │ ├─ routing_dev.yml + │ └─ security.yml + ├─ src/ + ├─ vendor/ + └─ web/ + +This default structure was chosen for its simplicity — one file per environment. +But as any other Symfony feature, you can customize it to better suit your needs. +The following sections explain different ways to organize your configuration +files. In order to simplify the examples, only the ``dev`` and ``prod`` +environments are taken into account. + +Different Directories per Environment +------------------------------------- + +Instead of suffixing the files with ``_dev`` and ``_prod``, this technique +groups all the related configuration files under a directory with the same +name as the environment: + +.. code-block:: text + + / + ├─ app/ + │ └─ config/ + │ ├─ common/ + │ │ ├─ config.yml + │ │ ├─ parameters.yml + │ │ ├─ routing.yml + │ │ └─ security.yml + │ ├─ dev/ + │ │ ├─ config.yml + │ │ ├─ parameters.yml + │ │ ├─ routing.yml + │ │ └─ security.yml + │ └─ prod/ + │ ├─ config.yml + │ ├─ parameters.yml + │ ├─ routing.yml + │ └─ security.yml + ├─ src/ + ├─ vendor/ + └─ web/ + +To make this work, change the code of the +:method:`Symfony\\Component\\HttpKernel\\KernelInterface::registerContainerConfiguration` +method:: + + // app/AppKernel.php + use Symfony\Component\HttpKernel\Kernel; + use Symfony\Component\Config\Loader\LoaderInterface; + + class AppKernel extends Kernel + { + // ... + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/'.$this->getEnvironment().'/config.yml'); + } + } + +Then, make sure that each ``config.yml`` file loads the rest of the configuration +files, including the common files. For instance, this would be the imports +needed for the ``app/config/dev/config.yml`` file: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/dev/config.yml + imports: + - { resource: '../common/config.yml' } + - { resource: 'parameters.yml' } + - { resource: 'security.yml' } + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/dev/config.php + $loader->import('../common/config.php'); + $loader->import('parameters.php'); + $loader->import('security.php'); + + // ... + +Semantic Configuration Files +---------------------------- + +A different organization strategy may be needed for complex applications with +large configuration files. For instance, you could create one file per bundle +and several files to define all application services: + +.. code-block:: text + + / + ├─ app/ + │ └─ config/ + │ ├─ bundles/ + │ │ ├─ bundle1.yml + │ │ ├─ bundle2.yml + │ │ ├─ ... + │ │ └─ bundleN.yml + │ ├─ environments/ + │ │ ├─ common.yml + │ │ ├─ dev.yml + │ │ └─ prod.yml + │ ├─ routing/ + │ │ ├─ common.yml + │ │ ├─ dev.yml + │ │ └─ prod.yml + │ └─ services/ + │ ├─ frontend.yml + │ ├─ backend.yml + │ ├─ ... + │ └─ security.yml + ├─ src/ + ├─ vendor/ + └─ web/ + +Again, change the code of the ``registerContainerConfiguration()`` method to +make Symfony aware of the new file organization:: + + // app/AppKernel.php + use Symfony\Component\HttpKernel\Kernel; + use Symfony\Component\Config\Loader\LoaderInterface; + + class AppKernel extends Kernel + { + // ... + + public function registerContainerConfiguration(LoaderInterface $loader) + { + $loader->load(__DIR__.'/config/environments/'.$this->getEnvironment().'.yml'); + } + } + +Following the same technique explained in the previous section, make sure to +import the appropriate configuration files from each main file (``common.yml``, +``dev.yml`` and ``prod.yml``). + +Advanced Techniques +------------------- + +Symfony loads configuration files using the +:doc:`Config component `, which provides some +advanced features. + +Mix and Match Configuration Formats +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Configuration files can import files defined with any other built-in configuration +format (``.yml``, ``.xml``, ``.php``, ``.ini``): + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + imports: + - { resource: 'parameters.yml' } + - { resource: 'services.xml' } + - { resource: 'security.yml' } + - { resource: 'legacy.php' } + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $loader->import('parameters.yml'); + $loader->import('services.xml'); + $loader->import('security.yml'); + $loader->import('legacy.php'); + + // ... + +.. caution:: + + The ``IniFileLoader`` parses the file contents using the + :phpfunction:`parse_ini_file` function. Therefore, you can only set + parameters to string values. Use one of the other loaders if you want + to use other data types (e.g. boolean, integer, etc.). + +If you use any other configuration format, you have to define your own loader +class extending it from :class:`Symfony\\Component\\DependencyInjection\\Loader\\FileLoader`. +When the configuration values are dynamic, you can use the PHP configuration +file to execute your own logic. In addition, you can define your own services +to load configurations from databases or web services. + +Global Configuration Files +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some system administrators may prefer to store sensitive parameters in files +outside the project directory. Imagine that the database credentials for your +website are stored in the ``/etc/sites/mysite.com/parameters.yml`` file. Loading +this file is as simple as indicating the full file path when importing it from +any other configuration file: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + imports: + - { resource: 'parameters.yml' } + - { resource: '/etc/sites/mysite.com/parameters.yml' } + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $loader->import('parameters.yml'); + $loader->import('/etc/sites/mysite.com/parameters.yml'); + + // ... + +Most of the time, local developers won't have the same files that exist on the +production servers. For that reason, the Config component provides the +``ignore_errors`` option to silently discard errors when the loaded file +doesn't exist: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + imports: + - { resource: 'parameters.yml' } + - { resource: '/etc/sites/mysite.com/parameters.yml', ignore_errors: true } + + # ... + + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $loader->import('parameters.yml'); + $loader->import('/etc/sites/mysite.com/parameters.yml', null, true); + + // ... + +As you've seen, there are lots of ways to organize your configuration files. You +can choose one of these or even create your own custom way of organizing the +files. Don't feel limited by the Standard Edition that comes with Symfony. For even +more customization, see ":doc:`/cookbook/configuration/override_dir_structure`". diff --git a/cookbook/configuration/index.rst b/cookbook/configuration/index.rst index 69250747457..35b87ef0f2e 100644 --- a/cookbook/configuration/index.rst +++ b/cookbook/configuration/index.rst @@ -12,3 +12,4 @@ Configuration pdo_session_storage apache_router web_server_configuration + configuration_organization diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 9eb4b0ab330..fd2cad7623c 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -30,6 +30,7 @@ * :doc:`/cookbook/configuration/pdo_session_storage` * :doc:`/cookbook/configuration/apache_router` * :doc:`/cookbook/configuration/web_server_configuration` + * :doc:`/cookbook/configuration/configuration_organization` * :doc:`/cookbook/console/index`