Loading...

Don't use YAML to config your Symfony App

Symfony won't support YAML in version 6.

One year ago ago Fabian (author of Symfony) created issue in symfony github repository to help him migrate from XML/YAML components config files, some people get mad some like me become happy and in this article I will show You why.

PHP is faster

Yaml is universal language mainly use in systems configuration and it's not supported out of the box by PHP. To use it with php you need for example Symfony Yaml which have to provide parsing method. External component is one of main reason for me why we should leave it. PHP to use yaml config, needs to parse before and of course this takes some time, even up to 2ms for simple foo:bar, we should cache it (and symfony does) but I can imagine use cases when we can't.

IDE Support

Professional IDE like PHPStorm supports YAML but it's has not autocomplete as good like for PHP files especially out of the box.
For example, we have service which is deprecated by using attribute #[Deprecated]

In  YAML config IDE won't cross the deprecated class like it does for PHP, also sooner or later you will breake some tests because of one missing space in your config file.

Constants

Using PHP constant in yaml can be tough, because for default everything is string, so Symfony/Yaml component includes extension to use constants but it doesn't looks good.

foo:
	bar: !php/const PHP_INT_MAX

Without !php/const is just a string, so it is parsed to array ['foo' => ['bar' => 'PHP_INT_MAX']].

In PHP config you can just use constants and when you want to change it's value you are doing it without search phrase in enteire project.

For example if you config role_hierarchy in PHP with value class for constants you can easily use this constants in controller method attribute to check if user has definded role.

config/role_hierarchy.php

return static function(ContainerConfigurator $configurator): void {
    $configurator->extension('security', [
        'role_hierarchy' => [
            Roles::ROLE_INACTIVE,
            Roles::ROLE_USER,
            Roles::ROLE_WRITER => Roles::ROLE_USER,
            Roles::ROLE_ADMIN => Roles::ROLE_WRITER
        ]
    ]);
};


For action to get logged user data im using attribute (new in php 8) with constant for ROLE_USER

src/Controller/UserController.php

#[Route(path: self::ROUTE_USER_INFO, name: "api_users_me", methods: [Request::METHOD_GET])]
#[IsGranted(Roles::ROLE_USER)]
public function me(TokenStorageInterface $tokenStorage): JsonResponse
{
    ...
}

How to switch to YAML

It's easy, just define all your yaml files as php and return static  function.

security:
	encoders:
		App\Entity\User:
			algorithm: auto

In function body we have to use method extension of ContainerConfigurator class which needs name of extension to configure, here we have security.

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->extension('security', [
        User::class => [
            'algorithm' => 'auto'
        ]
    ]);
};

Just kidding, we have tool for that and of course You can use PHP config with YAML and XML but I prefer to stick for one type of configuration and disable YAML/XML in Kernel.php

 

Be carefull, some symfony packages can use Yaml without dependency in composer.json because back in the time it was included for prod env in symfony. I had this issue on prod env because in dev composer installed symfony/yaml for other library so had to make PR to make it works on prod.
https://github.com/markitosgv/JWTRefreshTokenBundle/pull/223

 

To do this we need to install config transformer created by symplify for dev environment

composer require symplify/config-transformer --dev

After installing symplify we can run it to switch format by providing 3 parameters, input for us its YAML, next output PHP and last is a path of folder where this files exists.

vendor/bin/config-transformer switch-format -i yaml -o php config

After execute switch-format command, our yaml configs disapper and new php files are created, of course they are not perfect so we can to take a look what it's created.