New in Symfony 5.3: Config Builder Classes

Symfony 5.3 is backed by JoliCode. JoliCode is a team of passionate developers and open-source lovers, with a strong expertise in PHP & Symfony technologies. They can help you build your projects using state-of-the-art practices.

Symfony 5.3 will be released in May 2021. This is the first article of the series that shows the most important new features introduced by this Symfony version.


Contributed by
Tobias Nyholm
in #40600.

Symfony applications can use YAML, XML and/or PHP as their configuration format. Each of them has its advantages and its drawbacks, so we intend to keep supporting the three of them equally in the future.

In 2020 Symfony moved all its internal container configuration from XML to PHP thanks to a colossal community effort. This container configuration uses a fluent interface pattern based on methods like service(), args(), etc. However, the PHP configuration of packages/bundles is still based on big arrays like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// config/packages/security.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $container) {
  $array = [
        'firewalls' => [
            'main' => [
                'pattern' => '^/*',
                'lazy' => true,
                'anonymous' => [],
            ],
        ],
        'access_control' => [
            ['path' => '^/admin', 'roles' => 'ROLE_ADMIN'],
        ],
    ];

    $container->extension('security', $array);
}

In Symfony 5.3 we’re improving the PHP config of packages/bundles thanks to the new Config Builder Classes. These classes are generated automatically in your project build directory and transform your bundle configuration classes into fluent interface classes with methods named after your config options.

For example, in Symfony 5.3 you can keep configuring the security package with the PHP array shown above or you can use the following configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// config/packages/security.php
use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $security) {
    $security->firewall('main')
        ->pattern('^/*')
        ->lazy(true)
        ->anonymous();

    $security
        ->accessControl(['path' => '^/admin', 'roles' => 'ROLE_ADMIN']);
};

This new format is not only more concise and readable, but it’s also fully autocompletable by your IDE. Best of all, the SecurityConfig class used in this example is generated automatically by Symfony. We didn’t have to change anything in the security package.

These config builders are created for all packages/bundles of the application (even your own). For example, if you create a bundle with the acme_foo extension alias, Symfony will generate the Symfony\Config\AcmeFooConfig class for you (if your dependency injection extension changes, the class is regenerated; there’s a cache warmer to generate all config classes; etc.).

We intend to keep supporting YAML, XML and PHP formats equally in the future, but we hope that these new config builders will make you give PHP config a try. The new PHP config is as concise and readable as YAML, it provides better autocompletion than XML and it requires zero dependencies and extensions.

Help the Symfony project!

As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.

Comments

Amazing feature, thanks !!!
That's sexy indeed. But, can i be the devil's advocate and point out the Law of Demeter ?

Also, i'm not bothered by arrays, they reflect clearly the structure of the config param whereas here you need to indent properly to communicate what the setters returns.

So I have mixed feelings about this feature: nice trick, but might pinch us in the bottom at some point
@Julien I agree with some of the things you said. The new format is not perfect. However, in my opinion, the new config is far better because of its autocompletion.

With the new config builders, you only need to type "-" and ">" in your IDE to see all available options for some package/bundle.

With the traditional arrays, you need to memorize the option names or look for in Symfony Docs because there's no autocompletion, even when using an IDE.
@Javier indeed much more useable, the devil folds on this argument :D
Nice feature! If we upgrade from Symfony 5.2 to 5.3 will it auto generate the config class for us?
@fd6130 yes
Thanks 👍
Will save me many many hours
Nice feature, thank you for the work 👍
Great feature, thank you @tobias !
Thanks Tobias!!!
@Javier sorry, but coding-by-ide-autocompletion is not the holy grail of productivity nor correctness in my experience.

I have seen the problems with this "magic" happening frequently enough in Symfony projects with Phpstorm and junior developers, that I can now recognize them from orbit.

A short list of examples includes: typehint against concrete classes instead of typehinting against the available interfaces (because hey, that's what you get if you can debug the code up to that point or run similar code); typehint against the wrong interfaces (such as monolog\logger where psr would be a better choice); always use the methods of a class which come up first in the list presented by the IDE rather than the methods or properties which come up last but are more appropriate (and often do not do _exactly_ the thing which was required, but sound similar enough).

There is nothing that beats the knowledge that a developer gains by "reading the docs" of a given package/class before she starts using it, which means glancing over the _complete_ api at least once, be it in html form or in your IDE.

I am not saying that configuration classes are necessarily the ones which are more worthy of deep comprehension - I just want to warn about following blindly the "autocompletion good" mantra.

ps: why not `$security->accessControl()->path()` ?
@Gaetano I agree partially with you, specially about the interface vs implementation problem.

But I think this is different for ConfigBuilders. First, you need to type "use Symfony\Config\" and let the IDE show you all the available builders.

Second, I'm not claiming that developers shouldn't learn about the available options, but in my opinion, with the autocompletion of the fluent interface, you don't need to remember the exact name and spell of all of them (there are hundreds and hundreds of config options in Symfony!).
Does it allow dynamic configuration depending on request or something else? If it does, how config caching algorithm will separate cache ids?
It's the first time I see a static function, I can't find that in the php documentation, what is it ?
How is this supposed to work? Do I need to do some config? Because the classes that are supposed to be automatically generated are nowhere to be found for me.
@Thibault Vlacich same for me, can't find these classes anywhere.. :(
Correction: the classes are there, in var/cache/dev/Symfony/Config/, but PHPStorm was not finding them because I had excluded the var/cache folder entirely. Once I added var/cache/dev/Symfony/Config again, it detected them.

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.