New in Symfony 5.3: Config Builder Classes

Symfony 5.3 is backed by:
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
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
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
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
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.
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()` ?
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!).