mirror of
https://github.com/symfony/symfony-docs.git
synced 2026-03-23 16:22:10 +01:00
1391 lines
51 KiB
ReStructuredText
1391 lines
51 KiB
ReStructuredText
Configuring Symfony
|
||
===================
|
||
|
||
Configuration Files
|
||
-------------------
|
||
|
||
Symfony applications are configured with the files stored in the ``config/``
|
||
directory, which has this default structure:
|
||
|
||
.. code-block:: text
|
||
|
||
your-project/
|
||
├─ config/
|
||
│ ├─ packages/
|
||
│ ├─ bundles.php
|
||
│ ├─ routes.yaml
|
||
│ └─ services.yaml
|
||
|
||
* The ``routes.yaml`` file defines the :doc:`routing configuration </routing>`;
|
||
* The ``services.yaml`` file configures the services of the :doc:`service container </service_container>`;
|
||
* The ``bundles.php`` file enables/disables packages in your application;
|
||
* The ``config/packages/`` directory stores the configuration of every package
|
||
installed in your application.
|
||
|
||
Packages (also called "bundles" in Symfony and "plugins/modules" in other
|
||
projects) add ready-to-use features to your projects.
|
||
|
||
When using :ref:`Symfony Flex <symfony-flex>`, which is enabled by default in
|
||
Symfony applications, packages update the ``bundles.php`` file and create new
|
||
files in ``config/packages/`` automatically during their installation. For
|
||
example, this is the default file created by the "API Platform" bundle:
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/packages/api_platform.yaml
|
||
api_platform:
|
||
mapping:
|
||
paths: ['%kernel.project_dir%/src/Entity']
|
||
|
||
Splitting the configuration into lots of small files might seem intimidating to some
|
||
Symfony newcomers. However, you'll get used to them quickly and you rarely need
|
||
to change these files after package installation.
|
||
|
||
.. tip::
|
||
|
||
To learn about all the available configuration options, check out the
|
||
:doc:`Symfony Configuration Reference </reference/index>` or run the
|
||
``config:dump-reference`` command.
|
||
|
||
.. _configuration-formats:
|
||
|
||
Configuration Formats
|
||
~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Unlike other frameworks, Symfony doesn't impose a specific format on you to
|
||
configure your applications, but lets you choose between YAML, XML and PHP.
|
||
Throughout the Symfony documentation, all configuration examples will be
|
||
shown in these three formats.
|
||
|
||
There isn't any practical difference between formats. In fact, Symfony
|
||
transforms all of them into PHP and caches them before running the application,
|
||
so there's not even any performance difference.
|
||
|
||
YAML is used by default when installing packages because it's concise and very
|
||
readable. These are the main advantages and disadvantages of each format:
|
||
|
||
* **YAML**: simple, clean and readable, but not all IDEs support autocompletion
|
||
and validation for it. :doc:`Learn the YAML syntax </reference/formats/yaml>`;
|
||
* **XML**: autocompleted/validated by most IDEs and is parsed natively by PHP,
|
||
but sometimes it generates configuration considered too verbose. `Learn the XML syntax`_;
|
||
* **PHP**: very powerful and it allows you to create dynamic configuration with
|
||
arrays or a :ref:`ConfigBuilder <config-config-builder>`.
|
||
|
||
.. note::
|
||
|
||
By default Symfony loads the configuration files defined in YAML and PHP
|
||
formats. If you define configuration in XML format, update the
|
||
:method:`Symfony\\Bundle\\FrameworkBundle\\Kernel\\MicroKernelTrait::configureContainer`
|
||
and/or
|
||
:method:`Symfony\\Bundle\\FrameworkBundle\\Kernel\\MicroKernelTrait::configureRoutes`
|
||
methods in the ``src/Kernel.php`` file to add support for the ``.xml`` file
|
||
extension.
|
||
|
||
Importing Configuration Files
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Symfony loads configuration files using the :doc:`Config component
|
||
</components/config>`, which provides advanced features such as importing other
|
||
configuration files, even if they use a different format:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
imports:
|
||
- { resource: 'legacy_config.php' }
|
||
|
||
# glob expressions are also supported to load multiple files
|
||
- { resource: '/etc/myapp/*.yaml' }
|
||
|
||
# ignore_errors: not_found silently discards errors if the loaded file doesn't exist
|
||
- { resource: 'my_config_file.xml', ignore_errors: not_found }
|
||
# ignore_errors: true silently discards all errors (including invalid code and not found)
|
||
- { resource: 'my_other_config_file.xml', ignore_errors: true }
|
||
|
||
# ...
|
||
|
||
.. code-block:: 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"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
|
||
<imports>
|
||
<import resource="legacy_config.php"/>
|
||
<!-- glob expressions are also supported to load multiple files -->
|
||
<import resource="/etc/myapp/*.yaml"/>
|
||
|
||
<!-- ignore-errors="not_found" silently discards errors if the loaded file doesn't exist -->
|
||
<import resource="my_config_file.yaml" ignore-errors="not_found"/>
|
||
<!-- ignore-errors="true" silently discards all errors (including invalid code and not found) -->
|
||
<import resource="my_other_config_file.yaml" ignore-errors="true"/>
|
||
</imports>
|
||
|
||
<!-- ... -->
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/services.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->import('legacy_config.php');
|
||
|
||
// glob expressions are also supported to load multiple files
|
||
$container->import('/etc/myapp/*.yaml');
|
||
|
||
// the third optional argument of import() is 'ignore_errors'
|
||
// 'ignore_errors' set to 'not_found' silently discards errors if the loaded file doesn't exist
|
||
$container->import('my_config_file.yaml', null, 'not_found');
|
||
// 'ignore_errors' set to true silently discards all errors (including invalid code and not found)
|
||
$container->import('my_config_file.yaml', null, true);
|
||
};
|
||
|
||
// ...
|
||
|
||
.. _config-parameter-intro:
|
||
.. _config-parameters-yml:
|
||
.. _configuration-parameters:
|
||
|
||
Configuration Parameters
|
||
------------------------
|
||
|
||
Sometimes the same configuration value is used in several configuration files.
|
||
Instead of repeating it, you can define it as a "parameter", which is like a
|
||
reusable configuration value. By convention, parameters are defined under the
|
||
``parameters`` key in the ``config/services.yaml`` file:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
parameters:
|
||
# the parameter name is an arbitrary string (the 'app.' prefix is recommended
|
||
# to better differentiate your parameters from Symfony parameters).
|
||
app.admin_email: 'something@example.com'
|
||
|
||
# boolean parameters
|
||
app.enable_v2_protocol: true
|
||
|
||
# array/collection parameters
|
||
app.supported_locales: ['en', 'es', 'fr']
|
||
|
||
# binary content parameters (encode the contents with base64_encode())
|
||
app.some_parameter: !!binary VGhpcyBpcyBhIEJlbGwgY2hhciAH
|
||
|
||
# PHP constants as parameter values
|
||
app.some_constant: !php/const GLOBAL_CONSTANT
|
||
app.another_constant: !php/const App\Entity\BlogPost::MAX_ITEMS
|
||
|
||
# Enum case as parameter values
|
||
app.some_enum: !php/enum App\Enum\PostState::Published
|
||
|
||
# ...
|
||
|
||
.. code-block:: 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"
|
||
xmlns:framework="http://symfony.com/schema/dic/symfony"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
|
||
<parameters>
|
||
<!-- the parameter name is an arbitrary string (the 'app.' prefix is recommended
|
||
to better differentiate your parameters from Symfony parameters). -->
|
||
<parameter key="app.admin_email">something@example.com</parameter>
|
||
|
||
<!-- boolean parameters -->
|
||
<parameter key="app.enable_v2_protocol">true</parameter>
|
||
<!-- if you prefer to store the boolean value as a string in the parameter -->
|
||
<parameter key="app.enable_v2_protocol" type="string">true</parameter>
|
||
|
||
<!-- array/collection parameters -->
|
||
<parameter key="app.supported_locales" type="collection">
|
||
<parameter>en</parameter>
|
||
<parameter>es</parameter>
|
||
<parameter>fr</parameter>
|
||
</parameter>
|
||
|
||
<!-- binary content parameters (encode the contents with base64_encode()) -->
|
||
<parameter key="app.some_parameter" type="binary">VGhpcyBpcyBhIEJlbGwgY2hhciAH</parameter>
|
||
|
||
<!-- PHP constants as parameter values -->
|
||
<parameter key="app.some_constant" type="constant">GLOBAL_CONSTANT</parameter>
|
||
<parameter key="app.another_constant" type="constant">App\Entity\BlogPost::MAX_ITEMS</parameter>
|
||
|
||
<!-- Enum case as parameter values -->
|
||
<parameter key="app.some_enum" type="constant">App\Enum\PostState::Published</parameter>
|
||
</parameters>
|
||
|
||
<!-- ... -->
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/services.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
use App\Entity\BlogPost;
|
||
use App\Enum\PostState;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->parameters()
|
||
// the parameter name is an arbitrary string (the 'app.' prefix is recommended
|
||
// to better differentiate your parameters from Symfony parameters).
|
||
->set('app.admin_email', 'something@example.com')
|
||
|
||
// boolean parameters
|
||
->set('app.enable_v2_protocol', true)
|
||
|
||
// array/collection parameters
|
||
->set('app.supported_locales', ['en', 'es', 'fr'])
|
||
|
||
// binary content parameters (use the PHP escape sequences)
|
||
->set('app.some_parameter', 'This is a Bell char: \x07')
|
||
|
||
// PHP constants as parameter values
|
||
->set('app.some_constant', GLOBAL_CONSTANT)
|
||
->set('app.another_constant', BlogPost::MAX_ITEMS)
|
||
|
||
// Enum case as parameter values
|
||
->set('app.some_enum', PostState::Published);
|
||
};
|
||
|
||
// ...
|
||
|
||
.. warning::
|
||
|
||
By default and when using XML configuration, the values between ``<parameter>``
|
||
tags are not trimmed. This means that the value of the following parameter will be
|
||
``'\n something@example.com\n'``:
|
||
|
||
.. code-block:: xml
|
||
|
||
<parameter key="app.admin_email">
|
||
something@example.com
|
||
</parameter>
|
||
|
||
If you want to trim the value of your parameter, use the ``trim`` attribute.
|
||
When using it, the value of the following parameter will be ``something@example.com``:
|
||
|
||
.. code-block:: xml
|
||
|
||
<parameter key="app.admin_email" trim="true">
|
||
something@example.com
|
||
</parameter>
|
||
|
||
Once defined, you can reference this parameter value from any other
|
||
configuration file using a special syntax: wrap the parameter name in two ``%``
|
||
(e.g. ``%app.admin_email%``):
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/packages/some_package.yaml
|
||
some_package:
|
||
# any string surrounded by two % is replaced by that parameter value
|
||
email_address: '%app.admin_email%'
|
||
|
||
.. code-block:: xml
|
||
|
||
<!-- config/packages/some_package.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"
|
||
xmlns:framework="http://symfony.com/schema/dic/symfony"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
|
||
<!-- any string surrounded by two % is replaced by that parameter value -->
|
||
<some-package:config email-address="%app.admin_email%">
|
||
<!-- ... -->
|
||
</some-package:config>
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/packages/some_package.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
use function Symfony\Component\DependencyInjection\Loader\Configurator\param;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->extension('some_package', [
|
||
// when using the param() function, you only have to pass the parameter name...
|
||
'email_address' => param('app.admin_email'),
|
||
|
||
// ... but if you prefer it, you can also pass the name as a string
|
||
// surrounded by two % (same as in YAML and XML formats) and Symfony will
|
||
// replace it by that parameter value
|
||
'email_address' => '%app.admin_email%',
|
||
]);
|
||
};
|
||
|
||
.. note::
|
||
|
||
If some parameter value includes the ``%`` character, you need to escape it
|
||
by adding another ``%``, so Symfony doesn't consider it a reference to a
|
||
parameter name:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
parameters:
|
||
# Parsed as 'https://symfony.com/?foo=%s&bar=%d'
|
||
url_pattern: 'https://symfony.com/?foo=%%s&bar=%%d'
|
||
|
||
.. code-block:: xml
|
||
|
||
<!-- config/services.xml -->
|
||
<parameters>
|
||
<parameter key="url_pattern">http://symfony.com/?foo=%%s&bar=%%d</parameter>
|
||
</parameters>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/services.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->parameters()
|
||
->set('url_pattern', 'http://symfony.com/?foo=%%s&bar=%%d');
|
||
};
|
||
|
||
.. include:: /components/dependency_injection/_imports-parameters-note.rst.inc
|
||
|
||
Configuration parameters are very common in Symfony applications. Some packages
|
||
even define their own parameters (e.g. when installing the translation package,
|
||
a new ``locale`` parameter is added to the ``config/services.yaml`` file).
|
||
|
||
.. tip::
|
||
|
||
By convention, parameters whose names start with a dot ``.`` (for example,
|
||
``.mailer.transport``), are available only during the container compilation.
|
||
They are useful when working with :doc:`Compiler Passes </service_container/compiler_passes>`
|
||
to declare some temporary parameters that won't be available later in the application.
|
||
|
||
Configuration parameters are usually validation-free, but you can ensure that
|
||
essential parameters for your application's functionality are not empty::
|
||
|
||
/** @var ContainerBuilder $container */
|
||
$container->parameterCannotBeEmpty('app.private_key', 'Did you forget to set a value for the "app.private_key" parameter?');
|
||
|
||
If a non-empty parameter is ``null``, an empty string ``''``, or an empty array ``[]``,
|
||
Symfony will throw an exception. This validation is **not** made at compile time
|
||
but when attempting to retrieve the value of the parameter.
|
||
|
||
.. versionadded:: 7.2
|
||
|
||
Validating non-empty parameters was introduced in Symfony 7.2.
|
||
|
||
.. seealso::
|
||
|
||
Later in this article you can read how to
|
||
:ref:`get configuration parameters in controllers and services <configuration-accessing-parameters>`.
|
||
|
||
.. _page-creation-environments:
|
||
.. _page-creation-prod-cache-clear:
|
||
.. _configuration-environments:
|
||
|
||
Configuration Environments
|
||
--------------------------
|
||
|
||
You have only one application, but whether you realize it or not, you need it
|
||
to behave differently at different times:
|
||
|
||
* While **developing**, you want to log everything and expose nice debugging tools;
|
||
* After deploying to **production**, you want that same application to be
|
||
optimized for speed and only log errors.
|
||
|
||
The files stored in ``config/packages/`` are used by Symfony to configure the
|
||
:doc:`application services </service_container>`. In other words, you can change
|
||
the application behavior by changing which configuration files are loaded.
|
||
That's the idea of Symfony's **configuration environments**.
|
||
|
||
A typical Symfony application begins with three environments:
|
||
|
||
* ``dev`` for local development,
|
||
* ``prod`` for production servers,
|
||
* ``test`` for :doc:`automated tests </testing>`.
|
||
|
||
When running the application, Symfony loads the configuration files in this
|
||
order (the last files can override the values set in the previous ones):
|
||
|
||
#. The files in ``config/packages/*.<extension>``;
|
||
#. the files in ``config/packages/<environment-name>/*.<extension>``;
|
||
#. ``config/services.<extension>``;
|
||
#. ``config/services_<environment-name>.<extension>``.
|
||
|
||
Take the ``framework`` package, installed by default, as an example:
|
||
|
||
* First, ``config/packages/framework.yaml`` is loaded in all environments and
|
||
it configures the framework with some options;
|
||
* In the **prod** environment, nothing extra will be set as there is no
|
||
``config/packages/prod/framework.yaml`` file;
|
||
* In the **dev** environment, there is no file either (
|
||
``config/packages/dev/framework.yaml`` does not exist).
|
||
* In the **test** environment, the ``config/packages/test/framework.yaml`` file
|
||
is loaded to override some of the settings previously configured in
|
||
``config/packages/framework.yaml``.
|
||
|
||
In reality, each environment differs only somewhat from others. This means that
|
||
all environments share a large base of common configuration, which is put in
|
||
files directly in the ``config/packages/`` directory.
|
||
|
||
.. tip::
|
||
|
||
You can also define options for different environments in a single
|
||
configuration file using the special ``when`` keyword:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/packages/webpack_encore.yaml
|
||
webpack_encore:
|
||
# ...
|
||
output_path: '%kernel.project_dir%/public/build'
|
||
strict_mode: true
|
||
cache: false
|
||
|
||
# cache is enabled only in the "prod" environment
|
||
when@prod:
|
||
webpack_encore:
|
||
cache: true
|
||
|
||
# disable strict mode only in the "test" environment
|
||
when@test:
|
||
webpack_encore:
|
||
strict_mode: false
|
||
|
||
# YAML syntax allows you to reuse contents using "anchors" (&some_name) and "aliases" (*some_name).
|
||
# In this example, 'test' configuration uses the exact same configuration as in 'prod'
|
||
when@prod: &webpack_prod
|
||
webpack_encore:
|
||
# ...
|
||
when@test: *webpack_prod
|
||
|
||
.. code-block:: xml
|
||
|
||
<!-- config/packages/webpack_encore.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
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
<webpack-encore:config
|
||
output-path="%kernel.project_dir%/public/build"
|
||
strict-mode="true"
|
||
cache="false"
|
||
/>
|
||
|
||
<!-- cache is enabled only in the "test" environment -->
|
||
<when env="prod">
|
||
<webpack-encore:config cache="true"/>
|
||
</when>
|
||
|
||
<!-- disable strict mode only in the "test" environment -->
|
||
<when env="test">
|
||
<webpack-encore:config strict-mode="false"/>
|
||
</when>
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/packages/framework.php
|
||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||
use Symfony\Config\WebpackEncoreConfig;
|
||
|
||
return static function (WebpackEncoreConfig $webpackEncore, ContainerConfigurator $container): void {
|
||
$webpackEncore
|
||
->outputPath('%kernel.project_dir%/public/build')
|
||
->strictMode(true)
|
||
->cache(false)
|
||
;
|
||
|
||
// cache is enabled only in the "prod" environment
|
||
if ('prod' === $container->env()) {
|
||
$webpackEncore->cache(true);
|
||
}
|
||
|
||
// disable strict mode only in the "test" environment
|
||
if ('test' === $container->env()) {
|
||
$webpackEncore->strictMode(false);
|
||
}
|
||
};
|
||
|
||
.. seealso::
|
||
|
||
See the ``configureContainer()`` method of
|
||
:doc:`the Kernel class </configuration/front_controllers_and_kernel>` to
|
||
learn everything about the loading order of configuration files.
|
||
|
||
.. _selecting-the-active-environment:
|
||
|
||
Selecting the Active Environment
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Symfony applications come with a file called ``.env`` located at the project
|
||
root directory. This file is used to define the value of environment variables
|
||
and it's explained in detail :ref:`later in this article <config-dot-env>`.
|
||
|
||
Open the ``.env`` file (or better, the ``.env.local`` file if you created one)
|
||
and edit the value of the ``APP_ENV`` variable to change the environment in
|
||
which the application runs. For example, to run the application in production:
|
||
|
||
.. code-block:: bash
|
||
|
||
# .env (or .env.local)
|
||
APP_ENV=prod
|
||
|
||
This value is used both for the web and for the console commands. However, you
|
||
can override it for commands by setting the ``APP_ENV`` value before running them:
|
||
|
||
.. code-block:: terminal
|
||
|
||
# Use the environment defined in the .env file
|
||
$ php bin/console command_name
|
||
|
||
# Ignore the .env file and run this command in production
|
||
$ APP_ENV=prod php bin/console command_name
|
||
|
||
Creating a New Environment
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
The default three environments provided by Symfony are enough for most projects,
|
||
but you can define your own environments too. For example, this is how you can
|
||
define a ``staging`` environment where the client can test the project before
|
||
going to production:
|
||
|
||
#. Create a configuration directory with the same name as the environment (in
|
||
this case, ``config/packages/staging/``);
|
||
#. Add the needed configuration files in ``config/packages/staging/`` to
|
||
define the behavior of the new environment. Symfony loads the
|
||
``config/packages/*.yaml`` files first, so you only need to configure the
|
||
differences to those files;
|
||
#. Select the ``staging`` environment using the ``APP_ENV`` env var as explained
|
||
in the previous section.
|
||
|
||
.. tip::
|
||
|
||
It's common for environments to be similar to each other, so you can
|
||
use `symbolic links`_ between ``config/packages/<environment-name>/``
|
||
directories to reuse the same configuration.
|
||
|
||
Instead of creating new environments, you can use environment variables as
|
||
explained in the following section. This way you can use the same application
|
||
and environment (e.g. ``prod``) but change its behavior thanks to the
|
||
configuration based on environment variables (e.g. to run the application in
|
||
different scenarios: staging, quality assurance, client review, etc.)
|
||
|
||
.. _config-env-vars:
|
||
|
||
Configuration Based on Environment Variables
|
||
--------------------------------------------
|
||
|
||
Using `environment variables`_ (or "env vars" for short) is a common practice to:
|
||
|
||
* Configure options that depend on where the application is run (e.g. the database
|
||
credentials are usually different in production versus your local machine);
|
||
* Configure options that can change dynamically in a production environment (e.g.
|
||
to update the value of an expired API key without having to redeploy the entire
|
||
application).
|
||
|
||
In other cases, it's recommended to keep using :ref:`configuration parameters <configuration-parameters>`.
|
||
|
||
Use the special syntax ``%env(ENV_VAR_NAME)%`` to reference environment variables.
|
||
The values of these options are resolved at runtime (only once per request, to
|
||
not impact performance) so you can change the application behavior without having
|
||
to clear the cache.
|
||
|
||
This example shows how you could configure the application secret using an env var:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/packages/framework.yaml
|
||
framework:
|
||
# by convention the env var names are always uppercase
|
||
secret: '%env(APP_SECRET)%'
|
||
# ...
|
||
|
||
.. code-block:: xml
|
||
|
||
<!-- config/packages/framework.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"
|
||
xmlns:framework="http://symfony.com/schema/dic/framework"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
|
||
<!-- by convention the env var names are always uppercase -->
|
||
<framework:config secret="%env(APP_SECRET)%"/>
|
||
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/packages/framework.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->extension('framework', [
|
||
// by convention the env var names are always uppercase
|
||
'secret' => '%env(APP_SECRET)%',
|
||
]);
|
||
};
|
||
|
||
.. note::
|
||
|
||
Your env vars can also be accessed via the PHP super globals ``$_ENV`` and
|
||
``$_SERVER`` (both are equivalent)::
|
||
|
||
$databaseUrl = $_ENV['DATABASE_URL']; // mysql://db_user:db_password@127.0.0.1:3306/db_name
|
||
$env = $_SERVER['APP_ENV']; // prod
|
||
|
||
However, in Symfony applications there's no need to use this, because the
|
||
configuration system provides a better way of working with env vars.
|
||
|
||
.. seealso::
|
||
|
||
The values of env vars can only be strings, but Symfony includes some
|
||
:doc:`env var processors </configuration/env_var_processors>` to transform
|
||
their contents (e.g. to turn a string value into an integer).
|
||
|
||
To define the value of an env var, you have several options:
|
||
|
||
* :ref:`Add the value to a .env file <config-dot-env>`;
|
||
* :ref:`Encrypt the value as a secret <configuration-secrets>`;
|
||
* Set the value as a real environment variable in your shell or your web server.
|
||
|
||
If your application tries to use an env var that hasn't been defined, you'll see
|
||
an exception. You can prevent that by defining a default value for the env var.
|
||
To do so, define a parameter with the same name as the env var using this syntax:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/packages/framework.yaml
|
||
parameters:
|
||
# if the SECRET env var value is not defined anywhere, Symfony uses this value
|
||
env(SECRET): 'some_secret'
|
||
|
||
# ...
|
||
|
||
.. code-block:: xml
|
||
|
||
<!-- config/packages/framework.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"
|
||
xmlns:framework="http://symfony.com/schema/dic/symfony"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd
|
||
http://symfony.com/schema/dic/symfony
|
||
https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
|
||
|
||
<parameters>
|
||
<!-- if the SECRET env var value is not defined anywhere, Symfony uses this value -->
|
||
<parameter key="env(SECRET)">some_secret</parameter>
|
||
</parameters>
|
||
|
||
<!-- ... -->
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/packages/framework.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||
use Symfony\Config\FrameworkConfig;
|
||
|
||
return static function (ContainerBuilder $container, FrameworkConfig $framework) {
|
||
// if the SECRET env var value is not defined anywhere, Symfony uses this value
|
||
$container->setParameter('env(SECRET)', 'some_secret');
|
||
|
||
// ...
|
||
};
|
||
|
||
.. tip::
|
||
|
||
Some hosts - like Upsun - offer easy `utilities to manage env vars`_
|
||
in production.
|
||
|
||
.. note::
|
||
|
||
Some configuration features are not compatible with env vars. For example,
|
||
defining some container parameters conditionally based on the existence of
|
||
another configuration option. When using an env var, the configuration option
|
||
always exists, because its value will be ``null`` when the related env var
|
||
is not defined.
|
||
|
||
.. danger::
|
||
|
||
Beware that dumping the contents of the ``$_SERVER`` and ``$_ENV`` variables
|
||
or outputting the ``phpinfo()`` contents will display the values of the
|
||
environment variables, exposing sensitive information such as the database
|
||
credentials.
|
||
|
||
The values of the env vars are also exposed in the web interface of the
|
||
:doc:`Symfony profiler </profiler>`. In practice this shouldn't be a
|
||
problem because the web profiler must **never** be enabled in production.
|
||
|
||
.. _configuration-env-var-in-dev:
|
||
.. _config-dot-env:
|
||
|
||
Configuring Environment Variables in .env Files
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Instead of defining env vars in your shell or your web server, Symfony provides
|
||
a convenient way to define them inside a ``.env`` (with a leading dot) file
|
||
located at the root of your project.
|
||
|
||
The ``.env`` file is read and parsed on every request and its env vars are added
|
||
to the ``$_ENV`` & ``$_SERVER`` PHP variables. Any existing env vars are *never*
|
||
overwritten by the values defined in ``.env``, so you can combine both.
|
||
|
||
For example, to define the ``DATABASE_URL`` env var shown earlier in this article,
|
||
you can add:
|
||
|
||
.. code-block:: bash
|
||
|
||
# .env
|
||
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"
|
||
|
||
This file should be committed to your repository and (due to that fact) should
|
||
only contain "default" values that are good for local development. This file
|
||
should not contain production values.
|
||
|
||
In addition to your own env vars, this ``.env`` file also contains the env vars
|
||
defined by the third-party packages installed in your application (they are
|
||
added automatically by :ref:`Symfony Flex <symfony-flex>` when installing packages).
|
||
|
||
.. tip::
|
||
|
||
Since the ``.env`` file is read and parsed on every request, you don't need to
|
||
clear the Symfony cache or restart the PHP container if you're using Docker.
|
||
|
||
.env File Syntax
|
||
................
|
||
|
||
Add comments by prefixing them with ``#``:
|
||
|
||
.. code-block:: bash
|
||
|
||
# database credentials
|
||
DB_USER=root
|
||
DB_PASS=pass # this is the secret password
|
||
|
||
Use environment variables in values by prefixing variables with ``$``:
|
||
|
||
.. code-block:: bash
|
||
|
||
DB_USER=root
|
||
DB_PASS=${DB_USER}pass # include the user as a password prefix
|
||
|
||
.. warning::
|
||
|
||
The order is important when some env var depends on the value of other env
|
||
vars. In the above example, ``DB_PASS`` must be defined after ``DB_USER``.
|
||
Moreover, if you define multiple ``.env`` files and put ``DB_PASS`` first,
|
||
its value will depend on the ``DB_USER`` value defined in other files
|
||
instead of the value defined in this file.
|
||
|
||
Define a default value in case the environment variable is not set:
|
||
|
||
.. code-block:: bash
|
||
|
||
DB_USER=
|
||
DB_PASS=${DB_USER:-root}pass # results in DB_PASS=rootpass
|
||
|
||
Wrap values with single quotes to use them as literal strings where ``$``,
|
||
``#`` and other special characters have no special meaning:
|
||
|
||
.. code-block:: bash
|
||
|
||
DB_PASS='p@ss#w$rd'
|
||
|
||
With double quotes, variables are still interpolated but ``#`` and other
|
||
characters are treated as literal:
|
||
|
||
.. code-block:: bash
|
||
|
||
DB_PASS="p@ss#word"
|
||
DB_NAME="my_${DB_USER}_database"
|
||
|
||
Embed commands via ``$()`` (not supported on Windows):
|
||
|
||
.. code-block:: bash
|
||
|
||
START_TIME=$(date)
|
||
|
||
.. warning::
|
||
|
||
Using ``$()`` might not work depending on your shell.
|
||
|
||
.. tip::
|
||
|
||
As a ``.env`` file is a regular shell script, you can ``source`` it in
|
||
your own shell scripts:
|
||
|
||
.. code-block:: terminal
|
||
|
||
$ source .env
|
||
|
||
.. _configuration-multiple-env-files:
|
||
|
||
Overriding Environment Values via .env.local
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
If you need to override an environment value (e.g. to a different value on your
|
||
local machine), you can do that in a ``.env.local`` file:
|
||
|
||
.. code-block:: bash
|
||
|
||
# .env.local
|
||
DATABASE_URL="mysql://root:@127.0.0.1:3306/my_database_name"
|
||
|
||
This file should be ignored by git and should *not* be committed to your repository.
|
||
Several other ``.env`` files are available to set environment variables in *just*
|
||
the right situation:
|
||
|
||
* ``.env``: defines the default values of the env vars needed by the application;
|
||
* ``.env.local``: overrides the default values for all environments but only on
|
||
the machine which contains the file. This file should not be committed to the
|
||
repository and it's ignored in the ``test`` environment (because tests should
|
||
produce the same results for everyone);
|
||
* ``.env.<environment>`` (e.g. ``.env.test``): overrides env vars only for one
|
||
environment but for all machines (these files *are* committed);
|
||
* ``.env.<environment>.local`` (e.g. ``.env.test.local``): defines machine-specific
|
||
env var overrides only for one environment. It's similar to ``.env.local``,
|
||
but the overrides only apply to one environment.
|
||
|
||
*Real* environment variables always win over env vars created by any of the
|
||
``.env`` files. Note that this behavior depends on the
|
||
`variables_order <http://php.net/manual/en/ini.core.php#ini.variables-order>`_
|
||
configuration, which must contain an ``E`` to expose the ``$_ENV`` superglobal.
|
||
This is the default configuration in PHP.
|
||
|
||
The ``.env`` and ``.env.<environment>`` files should be committed to the
|
||
repository because they are the same for all developers and machines. However,
|
||
the env files ending in ``.local`` (``.env.local`` and ``.env.<environment>.local``)
|
||
**should not be committed** because only you will use them. In fact, the
|
||
``.gitignore`` file that comes with Symfony prevents them from being committed.
|
||
|
||
Overriding Environment Variables Defined By The System
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
If you need to override an environment variable defined by the system, use the
|
||
``overrideExistingVars`` parameter defined by the
|
||
:method:`Symfony\\Component\\Dotenv\\Dotenv::loadEnv`,
|
||
:method:`Symfony\\Component\\Dotenv\\Dotenv::bootEnv`, and
|
||
:method:`Symfony\\Component\\Dotenv\\Dotenv::populate` methods::
|
||
|
||
use Symfony\Component\Dotenv\Dotenv;
|
||
|
||
$dotenv = new Dotenv();
|
||
$dotenv->loadEnv(__DIR__.'/.env', overrideExistingVars: true);
|
||
|
||
// ...
|
||
|
||
This will override environment variables defined by the system but it **won't**
|
||
override environment variables defined in ``.env`` files.
|
||
|
||
.. _configuration-env-var-in-prod:
|
||
|
||
Configuring Environment Variables in Production
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
In production, the ``.env`` files are also parsed and loaded on each request. So
|
||
the easiest way to define env vars is by creating a ``.env.local`` file on your
|
||
production server(s) with your production values.
|
||
|
||
To improve performance, you can optionally run the ``dump-env`` Composer command:
|
||
|
||
.. code-block:: terminal
|
||
|
||
# parses ALL .env files and dumps their final values to .env.local.php
|
||
$ composer dump-env prod
|
||
|
||
.. sidebar:: Dumping Environment Variables without Composer
|
||
|
||
If you don't have Composer installed in production, you can use the
|
||
``dotenv:dump`` command instead (available in :ref:`Symfony Flex <symfony-flex>`
|
||
1.2 or later). The command is not registered by default, so you must register
|
||
first in your services:
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
services:
|
||
Symfony\Component\Dotenv\Command\DotenvDumpCommand: ~
|
||
|
||
Then, run the command:
|
||
|
||
.. code-block:: terminal
|
||
|
||
# parses ALL .env files and dumps their final values to .env.local.php
|
||
$ APP_ENV=prod APP_DEBUG=0 php bin/console dotenv:dump
|
||
|
||
After running this command, Symfony will load the ``.env.local.php`` file to
|
||
get the environment variables and will not spend time parsing the ``.env`` files.
|
||
|
||
.. tip::
|
||
|
||
Update your deployment tools/workflow to run the ``dotenv:dump`` command after
|
||
each deploy to improve the application performance.
|
||
|
||
Storing Environment Variables In Other Files
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
By default, the environment variables are stored in the ``.env`` file located
|
||
at the root of your project. However, you can store them in other files in
|
||
multiple ways.
|
||
|
||
If you use the :doc:`Runtime component </components/runtime>`, the dotenv
|
||
path is part of the options you can set in your ``composer.json`` file:
|
||
|
||
.. code-block:: json
|
||
|
||
{
|
||
// ...
|
||
"extra": {
|
||
// ...
|
||
"runtime": {
|
||
"dotenv_path": "my/custom/path/to/.env"
|
||
}
|
||
}
|
||
}
|
||
|
||
As an alternate option, you can directly invoke the ``Dotenv`` class in your
|
||
``bootstrap.php`` file or any other file of your application::
|
||
|
||
use Symfony\Component\Dotenv\Dotenv;
|
||
|
||
(new Dotenv())->bootEnv(dirname(__DIR__).'my/custom/path/to/.env');
|
||
|
||
Symfony will then look for the environment variables in that file, but also in
|
||
the local and environment-specific files (e.g. ``.*.local`` and
|
||
``.*.<environment>.local``). Read
|
||
:ref:`how to override environment variables <configuration-multiple-env-files>`
|
||
to learn more about this.
|
||
|
||
If you need to know the path to the ``.env`` file that Symfony is using, you can
|
||
read the ``SYMFONY_DOTENV_PATH`` environment variable in your application.
|
||
|
||
.. versionadded:: 7.1
|
||
|
||
The ``SYMFONY_DOTENV_PATH`` environment variable was introduced in Symfony
|
||
7.1.
|
||
|
||
.. _configuration-secrets:
|
||
|
||
Encrypting Environment Variables (Secrets)
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Instead of defining a real environment variable or adding it to a ``.env`` file,
|
||
if the value of a variable is sensitive (e.g. an API key or a database password),
|
||
you can encrypt the value using the :doc:`secrets management system </configuration/secrets>`.
|
||
|
||
Listing Environment Variables
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Use the ``debug:dotenv`` command to understand how Symfony parses the different
|
||
``.env`` files to set the value of each environment variable:
|
||
|
||
.. code-block:: terminal
|
||
|
||
$ php bin/console debug:dotenv
|
||
|
||
Dotenv Variables & Files
|
||
========================
|
||
|
||
Scanned Files (in descending priority)
|
||
--------------------------------------
|
||
|
||
* ⨯ .env.local.php
|
||
* ⨯ .env.dev.local
|
||
* ✓ .env.dev
|
||
* ⨯ .env.local
|
||
* ✓ .env
|
||
|
||
Variables
|
||
---------
|
||
|
||
---------- ------- ---------- ------
|
||
Variable Value .env.dev .env
|
||
---------- ------- ---------- ------
|
||
FOO BAR n/a BAR
|
||
ALICE BOB BOB bob
|
||
---------- ------- ---------- ------
|
||
|
||
# look for a specific variable passing its full or partial name as an argument
|
||
$ php bin/console debug:dotenv foo
|
||
|
||
Additionally, and regardless of how you set environment variables, you can see all
|
||
environment variables, with their values, referenced in Symfony's container configuration,
|
||
you can also see the number of occurrences of each environment variable in the container:
|
||
|
||
.. code-block:: terminal
|
||
|
||
$ php bin/console debug:container --env-vars
|
||
|
||
------------ ----------------- ------------------------------------ -------------
|
||
Name Default value Real value Usage count
|
||
------------ ----------------- ------------------------------------ -------------
|
||
APP_SECRET n/a "471a62e2d601a8952deb186e44186cb3" 2
|
||
BAR n/a n/a 1
|
||
BAZ n/a "value" 0
|
||
FOO "[1, "2.5", 3]" n/a 1
|
||
------------ ----------------- ------------------------------------ -------------
|
||
|
||
# you can also filter the list of env vars by name:
|
||
$ php bin/console debug:container --env-vars foo
|
||
|
||
# run this command to show all the details for a specific env var:
|
||
$ php bin/console debug:container --env-var=FOO
|
||
|
||
Creating Your Own Logic To Load Env Vars
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
You can implement your own logic to load environment variables if the default
|
||
Symfony behavior doesn't fit your needs. To do so, create a service whose class
|
||
implements :class:`Symfony\\Component\\DependencyInjection\\EnvVarLoaderInterface`.
|
||
|
||
.. note::
|
||
|
||
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
|
||
the autoconfiguration feature will enable and tag this service automatically.
|
||
Otherwise, you need to register and :doc:`tag your service </service_container/tags>`
|
||
with the ``container.env_var_loader`` tag.
|
||
|
||
Let's say you have a JSON file named ``env.json`` containing your environment
|
||
variables:
|
||
|
||
.. code-block:: json
|
||
|
||
{
|
||
"vars": {
|
||
"APP_ENV": "prod",
|
||
"APP_DEBUG": false
|
||
}
|
||
}
|
||
|
||
You can define a class like the following ``JsonEnvVarLoader`` to populate the
|
||
environment variables from the file::
|
||
|
||
namespace App\DependencyInjection;
|
||
|
||
use Symfony\Component\DependencyInjection\EnvVarLoaderInterface;
|
||
|
||
final class JsonEnvVarLoader implements EnvVarLoaderInterface
|
||
{
|
||
private const ENV_VARS_FILE = 'env.json';
|
||
|
||
public function loadEnvVars(): array
|
||
{
|
||
$fileName = __DIR__.\DIRECTORY_SEPARATOR.self::ENV_VARS_FILE;
|
||
if (!is_file($fileName)) {
|
||
// throw an exception or just ignore this loader, depending on your needs
|
||
}
|
||
|
||
$content = json_decode(file_get_contents($fileName), true);
|
||
|
||
return $content['vars'];
|
||
}
|
||
}
|
||
|
||
That's it! Now the application will look for a ``env.json`` file in the
|
||
current directory to populate environment variables (in addition to the
|
||
already existing ``.env`` files).
|
||
|
||
.. tip::
|
||
|
||
If you want an env var to have a value on a certain environment but to fallback
|
||
on loaders on another environment, assign an empty value to the env var for
|
||
the environment you want to use loaders:
|
||
|
||
.. code-block:: bash
|
||
|
||
# .env (or .env.local)
|
||
APP_ENV=prod
|
||
|
||
# .env.prod (or .env.prod.local) - this will fallback on the loaders you defined
|
||
APP_ENV=
|
||
|
||
.. _configuration-accessing-parameters:
|
||
|
||
Accessing Configuration Parameters
|
||
----------------------------------
|
||
|
||
Controllers and services can access all the configuration parameters. This
|
||
includes both the :ref:`parameters defined by yourself <configuration-parameters>`
|
||
and the parameters created by packages/bundles. Run the following command to see
|
||
all the parameters that exist in your application:
|
||
|
||
.. code-block:: terminal
|
||
|
||
$ php bin/console debug:container --parameters
|
||
|
||
In controllers extending from the :ref:`AbstractController <the-base-controller-class-services>`,
|
||
use the ``getParameter()`` helper::
|
||
|
||
// src/Controller/UserController.php
|
||
namespace App\Controller;
|
||
|
||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
|
||
class UserController extends AbstractController
|
||
{
|
||
// ...
|
||
|
||
public function index(): Response
|
||
{
|
||
$projectDir = $this->getParameter('kernel.project_dir');
|
||
$adminEmail = $this->getParameter('app.admin_email');
|
||
|
||
// ...
|
||
}
|
||
}
|
||
|
||
In services and controllers not extending from ``AbstractController``, inject
|
||
the parameters as arguments of their constructors. You must inject them
|
||
explicitly because :doc:`service autowiring </service_container/autowiring>`
|
||
doesn't work for parameters:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
parameters:
|
||
app.contents_dir: '...'
|
||
|
||
services:
|
||
App\Service\MessageGenerator:
|
||
arguments:
|
||
$contentsDir: '%app.contents_dir%'
|
||
|
||
.. code-block:: 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"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd">
|
||
|
||
<parameters>
|
||
<parameter key="app.contents_dir">...</parameter>
|
||
</parameters>
|
||
|
||
<services>
|
||
<service id="App\Service\MessageGenerator">
|
||
<argument key="$contentsDir">%app.contents_dir%</argument>
|
||
</service>
|
||
</services>
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/services.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
use App\Service\MessageGenerator;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->parameters()
|
||
->set('app.contents_dir', '...');
|
||
|
||
$container->services()
|
||
->get(MessageGenerator::class)
|
||
->arg('$contentsDir', '%app.contents_dir%');
|
||
};
|
||
|
||
If you inject the same parameters over and over again, use the
|
||
``services._defaults.bind`` option instead. The arguments defined in that option are
|
||
injected automatically whenever a service constructor or controller action
|
||
defines an argument with that exact name. For example, to inject the value of the
|
||
:ref:`kernel.project_dir parameter <configuration-kernel-project-directory>`
|
||
whenever a service/controller defines a ``$projectDir`` argument, use this:
|
||
|
||
.. configuration-block::
|
||
|
||
.. code-block:: yaml
|
||
|
||
# config/services.yaml
|
||
services:
|
||
_defaults:
|
||
bind:
|
||
# pass this value to any $projectDir argument for any service
|
||
# that's created in this file (including controller arguments)
|
||
$projectDir: '%kernel.project_dir%'
|
||
|
||
# ...
|
||
|
||
.. code-block:: 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"
|
||
xsi:schemaLocation="http://symfony.com/schema/dic/services
|
||
https://symfony.com/schema/dic/services/services-1.0.xsd">
|
||
|
||
<services>
|
||
<defaults autowire="true" autoconfigure="true" public="false">
|
||
<!-- pass this value to any $projectDir argument for any service
|
||
that's created in this file (including controller arguments) -->
|
||
<bind key="$projectDir">%kernel.project_dir%</bind>
|
||
</defaults>
|
||
|
||
<!-- ... -->
|
||
</services>
|
||
</container>
|
||
|
||
.. code-block:: php
|
||
|
||
// config/services.php
|
||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||
|
||
return static function (ContainerConfigurator $container): void {
|
||
$container->services()
|
||
->defaults()
|
||
// pass this value to any $projectDir argument for any service
|
||
// that's created in this file (including controller arguments)
|
||
->bind('$projectDir', '%kernel.project_dir%');
|
||
|
||
// ...
|
||
};
|
||
|
||
.. seealso::
|
||
|
||
Read the article about :ref:`binding arguments by name and/or type <services-binding>`
|
||
to learn more about this powerful feature.
|
||
|
||
Finally, if some service needs access to lots of parameters, instead of
|
||
injecting each of them individually, you can inject all the application
|
||
parameters at once by type-hinting any of its constructor arguments with the
|
||
:class:`Symfony\\Component\\DependencyInjection\\ParameterBag\\ContainerBagInterface`::
|
||
|
||
// src/Service/MessageGenerator.php
|
||
namespace App\Service;
|
||
|
||
// ...
|
||
|
||
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
|
||
|
||
class MessageGenerator
|
||
{
|
||
public function __construct(
|
||
private ContainerBagInterface $params,
|
||
) {
|
||
}
|
||
|
||
public function someMethod(): void
|
||
{
|
||
// get any container parameter from $this->params, which stores all of them
|
||
$sender = $this->params->get('mailer_sender');
|
||
// ...
|
||
}
|
||
}
|
||
|
||
.. _config-config-builder:
|
||
|
||
Using PHP ConfigBuilders
|
||
------------------------
|
||
|
||
Writing PHP config is sometimes difficult because you end up with large nested
|
||
arrays and you have no autocompletion help from your favorite IDE. A way to
|
||
address this is to use "ConfigBuilders". They are objects that will help you
|
||
build these arrays.
|
||
|
||
Symfony generates the ConfigBuilder classes automatically in the
|
||
:ref:`kernel build directory <configuration-kernel-build-directory>` for all the
|
||
bundles installed in your application. By convention they all live in the
|
||
namespace ``Symfony\Config``::
|
||
|
||
// config/packages/security.php
|
||
use Symfony\Config\SecurityConfig;
|
||
|
||
return static function (SecurityConfig $security): void {
|
||
$security->firewall('main')
|
||
->pattern('^/*')
|
||
->lazy(true)
|
||
->security(false);
|
||
|
||
$security
|
||
->roleHierarchy('ROLE_ADMIN', ['ROLE_USER'])
|
||
->roleHierarchy('ROLE_SUPER_ADMIN', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'])
|
||
->accessControl()
|
||
->path('^/user')
|
||
->roles('ROLE_USER');
|
||
|
||
$security->accessControl(['path' => '^/admin', 'roles' => 'ROLE_ADMIN']);
|
||
};
|
||
|
||
.. note::
|
||
|
||
Only root classes in the namespace ``Symfony\Config`` are ConfigBuilders.
|
||
Nested configs (e.g. ``\Symfony\Config\Framework\CacheConfig``) are regular
|
||
PHP objects which aren't autowired when using them as an argument type.
|
||
|
||
.. note::
|
||
|
||
In order to get ConfigBuilders autocompletion in your IDE/editor, make sure
|
||
to not exclude the directory where these classes are generated (by default,
|
||
in ``var/cache/dev/Symfony/Config/``).
|
||
|
||
Keep Going!
|
||
-----------
|
||
|
||
Congratulations! You've tackled the basics of Symfony. Next, learn about *each*
|
||
part of Symfony individually by following the guides. Check out:
|
||
|
||
* :doc:`/forms`
|
||
* :doc:`/doctrine`
|
||
* :doc:`/service_container`
|
||
* :doc:`/security`
|
||
* :doc:`/mailer`
|
||
* :doc:`/logging`
|
||
|
||
And all the other topics related to configuration:
|
||
|
||
.. toctree::
|
||
:maxdepth: 1
|
||
:glob:
|
||
|
||
configuration/*
|
||
|
||
.. _`Learn the XML syntax`: https://en.wikipedia.org/wiki/XML
|
||
.. _`environment variables`: https://en.wikipedia.org/wiki/Environment_variable
|
||
.. _`symbolic links`: https://en.wikipedia.org/wiki/Symbolic_link
|
||
.. _`utilities to manage env vars`: https://symfony.com/doc/current/cloud/env.html
|