DEV Community

david duymelinck
david duymelinck

Posted on

My 2 cents on the new Symfony PHP configuration format.

I just saw the post about the new PHP configuration format and it felt like going back in time.

The PHP configuration evolution.

Before Symfony 5.3

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

    $container->extension('security', $array);
}
Enter fullscreen mode Exit fullscreen mode

From Symfony 5.3 until the removal

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

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

The new format.

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

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

        'access_control' => [
            ['path' => '^/admin', 'roles' => 'ROLE_ADMIN'],
        ],
    ]
]);
Enter fullscreen mode Exit fullscreen mode

The research and thoughts

Based purely on syntax you can't deny it is very close to the Symfony 5.2 code.
The reason they give in the blog post to make the move is that generics are supported by enough tools to make it a viable solution.
I'm not a big fan of using tools to help you to write the correct code, if it is possible to write correct code without the need of tools.

I don't care if the config builder goes away. The builder pattern is a convenient way to write code, but it makes it easy to cause side effects while manipulating the object with the methods.

I have read the PR for more background information. And I agree that creating a configuration tree is very difficult and a more relaxed format removes edge cases.

My solution

While I didn't put that much thought into as the Symfony people, I'm thinking about PDO(like) objects.

The config example my way.

return [
   new Config\Security\Firewall('main')
         ->properties(pattern: '^/*', lazy: true, anonymus: true),
  new Config\Security\AccessControl(path: '^/admin', roles: 'ROLE_ADMIN'),
]
Enter fullscreen mode Exit fullscreen mode

The idea is to just return a flat array with specific Config types.
The constructor can accept global value(s).
If the settings are too much to add them all to the constructor use one or more methods to give them more context.

To avoid edge cases the constructor and/or methods could have a spread operator argument to accept configuration settings that are more niche.

This way builds on the strengths of the current PHP version:

  • type hinted arguments
  • named arguments
  • the spread operator

I also read one of the reasons of the change is to make it easier to go from YAML to PHP. And that is something that will be harder to do with my solution.

All in all, I think the new format is the best compromise to go forward. But it doesn't mean I don't see room for improvement.

Top comments (0)