Nicolas Grekas
Contributed by Nicolas Grekas in #62092 , #62129 and #62135

Back in Symfony 5.3 (released in May 2021), we introduced config builder classes as a fluent PHP interface for configuring Symfony applications. These classes were generated dynamically depending on which bundles were installed and made it possible to configure your app like this:

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']);
};

In Symfony 7.4, as part of the broader effort to modernize configuration formats (and since we're deprecating the XML configuration format), we're also deprecating the config builder classes and the fluent PHP configuration.

The main reason is technical: fluent configuration is not flexible enough and must match a single canonical interpretation of the semantic config tree. It also makes automatic configuration updates (via Symfony recipes) significantly harder.

So what's replacing the fluent format? We're introducing a new array-based PHP configuration format. The previous example now becomes:

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

return App::config([
    'security' => [
        // ...

        'firewalls' => [
            'main' => [
                'pattern' => '^/*',
                'lazy' => true,
                'anonymous' => true,
            ],
        ],

        'access_control' => [
            ['path' => '^/admin', 'roles' => 'ROLE_ADMIN'],
        ],
    ]
]);

If at first sight this looks like "just arrays", you're not wrong. It's simple, compact, and very familiar: much like YAML, but directly in PHP. However, there is a lot more to it.

To make this new format truly shine, Symfony now defines array shapes for all configuration. These are PHP metadata definitions that tools like PhpStorm, PHPStan, Psalm, and others can read and process. This means:

  • full autocompletion
  • static analysis
  • type validation
  • instant discoverability of every config option

As you can see, these are not ordinary arrays. They combine the readability of YAML with the tooling advantages of native PHP.

These shapes are generated dynamically based on the bundles installed in your application. The generated file is called reference.php and is stored in the config/ directory. You should commit it to your repository and optionally add a new entry in the autoload section of composer.json (for example, "classmap": ["config/"]).

We’re not ready yet to make this new format the recommended one. YAML still offers many advantages. However, this update opens the door to using PHP as a first-class configuration format in the future. The new approach is concise, expressive, easy to maintain, well-supported by modern tools, and benefits from the full power of PHP. What’s still missing? Not all static analyzers and IDEs fully support complex array shapes yet, Symfony Flex currently understands YAML only, and a few other pieces still need refinement before this vision can become reality. Even so, this marks an exciting step toward a more unified, powerful, and developer-friendly configuration experience in Symfony.

Published in #Living on the edge