New in Symfony 5.3: Configure Multiple Environments in a Single File

Contributed by
Nicolas Grekas
in #40214
and #40782.

Symfony defines different configuration environments so you can change your
application behavior depending on where it’s run (e.g. locally in your
development machine, in the production server, etc.)

The options applied to bundles/packages in all environments are defined in
config/packages/ and the specific options of each environment are defined in
config/packages/<environment>/.

This works well, but it’s cumbersome when the differences among environments are
minimal, because you need to create/maintain another config file just to change
a few config options.

That’s why in Symfony 5.3 you can also define options for different
environments in a single file
. The exact syntax to use depends on the format
of the config file.

In YAML config files, use the [email protected] special key:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/packages/webpack_encore.yaml
webpack_encore:
# …
output_path: ‚%kernel.project_dir%/public/build‘
strict_mode: true
cache: false

[email protected]:
webpack_encore:
cache: true

[email protected]:
webpack_encore:
strict_mode: false

In XML config, wrap the config in the new <when> tag:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!– config/packages/webpack_encore.xml –>
<?xml version=“1.0″ encoding=“UTF-8″ ?>
<container xmlns=„…“>
<webpack-encore:config>
<!– … –>
</webpack-encore:config>

<when env=„prod“>
<webpack-encore:config>
<!– … –>
</webpack-encore:config>
</when>

<when env=„test“>
<webpack-encore:config>
<!– … –>
</webpack-encore:config>
</when>
</container>

In PHP config files, use the new env() method to check in which
environment is the application running:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// config/packages/webpack_encore.php
use SymfonyComponentDependencyInjectionLoaderConfiguratorContainerConfigurator;

return static function (FrameworkConfig $framework, ContainerConfigurator $container) {
// …

if (‚prod‘ === $container->env()) {
// …
}

if (‚test‘ === $container->env()) {
$framework->test(true);
$framework->session()->storageFactoryId(’session.storage.mock_file‘);
}
};

This syntax also works to define routes and services only in some environments.
You can even combine all in a single file to configure some package and create
services but only for some environments:

1
2
3
4
5
6
7
8
9
10
11
framework:
secret: ‚%env(APP_SECRET)%‘

[email protected]:
services:
AppSomeServiceForDev: ~

[email protected]:
framework:
test: true
# …

The traditional way of using a config file per environment will keep working
in the future, but we encourage you to give this new feature a try to reduce
the number of config files to maintain.

Lastly, classes can now use PHP attributes to tell that they should only
be registered as services in some environments:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use SymfonyComponentDependencyInjectionAttributeWhen;

#[When(env: ‚dev‘)]
class SomeClass
{
// …
}

// you can apply more than one attribute to the same class:

#[When(env: ‚dev‘)]
#[When(env: ‚test‘)]
class AnotherClass
{
// …
}

Sponsor the Symfony project.

Symfony Blog
Read More

Latest News

PHP-Releases

PHP 8.0.19 released!

PHP 7.4.29 released!