Skip to content

Updated the configuration/* files #8732

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 57 additions & 246 deletions configuration/configuration_organization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,199 +9,63 @@ 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::
executes the ``configureContainer()`` method of the ``Kernel`` class::

// app/AppKernel.php
use Symfony\Component\HttpKernel\Kernel;
// src/Kernel.php
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel
{
// ...

public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getProjectDir().'/app/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

your-project/
├─ 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
├─ ...

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.
const CONFIG_EXTS = '.{php,xml,yaml,yml}';

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

your-project/
├─ 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
├─ ...

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)
public function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
{
$loader->load($this->getProjectDir().'/app/config/'.$this->getEnvironment().'/config.yml');
$confDir = $this->getProjectDir().'/config';
$loader->load($confDir.'/packages/*'.self::CONFIG_EXTS, 'glob');
if (is_dir($confDir.'/packages/'.$this->environment)) {
$loader->load($confDir.'/packages/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
}
$loader->load($confDir.'/services'.self::CONFIG_EXTS, 'glob');
$loader->load($confDir.'/services_'.$this->environment.self::CONFIG_EXTS, 'glob');
}
}

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:
For the ``dev`` environment, Symfony loads the following config files and
directories and in this order:

.. configuration-block::

.. code-block:: yaml

# app/config/dev/config.yml
imports:
- { resource: '../common/config.yml' }
- { resource: 'parameters.yml' }
- { resource: 'security.yml' }

# ...

.. code-block:: xml

<!-- app/config/dev/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<imports>
<import resource="../common/config.xml" />
<import resource="parameters.xml" />
<import resource="security.xml" />
</imports>

<!-- ... -->
</container>
#. ``config/packages/*``
#. ``config/packages/dev/*``
#. ``config/services.yaml``
#. ``config/services_dev.yaml``

.. code-block:: php

// app/config/dev/config.php
$loader->import('../common/config.php');
$loader->import('parameters.php');
$loader->import('security.php');

// ...

.. include:: /components/dependency_injection/_imports-parameters-note.rst.inc

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:
Therefore, the configuration files of the default Symfony applications follow
this structure:

.. code-block:: text

your-project/
├─ 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
├─ config/
│ └─ packages/
│ ├─ dev/
| │ ├─ framework.yaml
│ │ └─ ...
│ ├─ prod/
│ │ └─ ...
│ ├─ test/
│ │ └─ ...
| ├─ framework.yaml
│ └─ ...
│ ├─ services.yaml
│ └─ services_dev.yaml
├─ ...

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($this->getProjectDir().'/app/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``).
This default structure was chosen for its simplicity — one file per package and
environment. But as any other Symfony feature, you can customize it to better
suit your needs.

Advanced Techniques
-------------------
Expand All @@ -220,18 +84,16 @@ format (``.yml``, ``.xml``, ``.php``, ``.ini``):

.. code-block:: yaml

# app/config/config.yml
# config/services.yaml
imports:
- { resource: 'parameters.yml' }
- { resource: 'services.xml' }
- { resource: 'security.yml' }
- { resource: 'my_config_file.xml' }
- { resource: 'legacy.php' }

# ...

.. code-block:: xml

<!-- app/config/config.xml -->
<!-- config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand All @@ -241,9 +103,7 @@ format (``.yml``, ``.xml``, ``.php``, ``.ini``):
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<imports>
<import resource="parameters.yml" />
<import resource="services.xml" />
<import resource="security.yml" />
<import resource="my_config_file.yaml" />
<import resource="legacy.php" />
</imports>

Expand All @@ -252,21 +112,12 @@ format (``.yml``, ``.xml``, ``.php``, ``.ini``):

.. code-block:: php

// app/config/config.php
$loader->import('parameters.yml');
$loader->import('services.xml');
$loader->import('security.yml');
$loader->import('legacy.php');
// config/services.php
$loader->import('my_config_file.yaml');
$loader->import('legacy.xml');

// ...

.. 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
Expand All @@ -278,24 +129,23 @@ 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
website are stored in the ``/etc/sites/mysite.com/parameters.yaml`` 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
# config/services.yaml
imports:
- { resource: 'parameters.yml' }
- { resource: '/etc/sites/mysite.com/parameters.yml' }
- { resource: '/etc/sites/mysite.com/parameters.yaml', ignore_errors: true }

# ...

.. code-block:: xml

<!-- app/config/config.xml -->
<!-- config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand All @@ -305,65 +155,26 @@ any other configuration file:
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<imports>
<import resource="parameters.yml" />
<import resource="/etc/sites/mysite.com/parameters.yml" />
<import resource="/etc/sites/mysite.com/parameters.yaml" ignore-errors="true" />
</imports>

<!-- ... -->
</container>

.. code-block:: php

// app/config/config.php
$loader->import('parameters.yml');
$loader->import('/etc/sites/mysite.com/parameters.yml');
// config/services.php
$loader->import('/etc/sites/mysite.com/parameters.yaml', null, true);

// ...

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
.. tip::

# app/config/config.yml
imports:
- { resource: 'parameters.yml' }
- { resource: '/etc/sites/mysite.com/parameters.yml', ignore_errors: true }

# ...

.. code-block:: xml

<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<imports>
<import resource="parameters.yml" />
<import resource="/etc/sites/mysite.com/parameters.yml" ignore-errors="true" />
</imports>

<!-- ... -->
</container>

.. code-block:: php

// app/config/config.php
$loader->import('parameters.yml');
$loader->import('/etc/sites/mysite.com/parameters.yml', null, true);

// ...
The ``ignore_errors`` option (which is the third optional argument in the
loader's ``import()`` method) silently discards errors when the loaded file
doesn't exist. This is needed in this case because most of the time, local
developers won't have the same files that exist on the production servers.

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:`/configuration/override_dir_structure`".
files. For even more customization, see ":doc:`/configuration/override_dir_structure`".
Loading