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 functionregisterContainerConfiguration( LoaderInterface $loader) public functionconfigureContainer(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`".