10 Cool Features You Get after switching from YAML to PHP Configs

You've probably noticed Symfony is moving towards PHP configuration. If you're on XML or YAML, you'll most likely migrate to PHP with upcoming Symfony 6.

There are already tools that can help you migrate today - so it's not a matter of work, but a matter of choice.

Today we look at 10 cool features you get by switching to PHP configs that make you an even lazier programmer.

Do you care why this begun? Be sure to read Symfony issue:

The biggest advantage is IDE auto-completion out of the box,
and one XML/YAML language less to learn.

There are the cool features I've observed from migration of 50+ YAML configs to PHP:

1. Absolute Paths over Random Paths

In configs, we often define paths to files or directories. Could you tell me what exact path this is?

        - 'src'

We don't know. It depends on the internal tool implementation and luck.

Now the same config in PHP:

Pretty clear, right?

2. We Can See Deprecated Classes in PHPStorm

The YAML config will not show you, if class was deprecated:

PHP will cross the deprecated class and prepare you better for the future:

3. Missing Classes in Parameters

In YAML, everything is a string by default, so YAML doesn't know that you mean a class.

PHP show that pretty clearly:

4. IDE Autocomplete Just Works

Do you recall YAML struggle, when you want to register a service?

In PHP config you can forget it and just type:

Even with typos like "Appication" ;)

5. How was that calls Syntax?

Do you remember how to set a call on the service setup?

            # what now?

No, don't Google it! Try from the top of your head.

An intuitive way would be to use the same syntax as properties/arguments:

            'setValue': [1]

No :( then we have to Google it...

In PHP we can use intuitive approach and see what IDE tells us:

6. No More Magic YAML syntax for Constants

In YAML everything is a string:

    line_ending: PHP_EOL

Is that PHP_EOL constant as we know it? No, it's "PHP_EOL" string.

How can we specify a string that is a constant? (Feels weird for my brain just writing this sentence.)

Symfony 3.2 introduced special prefix: !php/const

    line_ending: !php/const PHP_EOL

Pretty crazy, right?

How does PHP solve this?

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

return static function (ContainerConfigurator $containerConfigurator): void {
    $parameters = $containerConfigurator->parameters();

    $parameters->set('line_ending', PHP_EOL);

It just works, no headache!

7. One Way to Add Arguments

These 2 files will produce the same configuration:

        # silent "arguments" key is omitted
        $key: value
            $key: value
            # or was it this?
            # key: value

In PHP this is just 1 clear way:

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

return static function (ContainerConfigurator $containerConfigurator): void {
    $services = $containerConfigurator->services();

        ->arg('key', 'value');

8. No More Magic Tags Without Name

For tags, these 2 files produce the same output:

            - kernel.event_subscriber
            # how do we extend this later?
            - { name: 'kernel.event_subscriber' }

In PHP, there is just 1 way for both:

9. ECS, Rector & PHPStan watches your Config Now

This feature is my favorite by far because it finally opens the door for next-level automation.

YAML doesn't have any static analyzer or instant upgrade tool. This makes the upgrade of Symfony projects double the work - in PHP, in YAML.

Since *.php is PHP code, all the powerful CI tools have access to it.

Fewer bugs, effortless changes, less upgrade work, new PHPStan rules, more fun coding.

10. Constants over Strings 🎉

Last but not least. You've probably noticed I hete typoes. I'm so used to tool watching my back, that I type much faster than my fingers can. Then I run the tools and code works (usually).

If you give me a choice of "string" or CONSTANT, 10 of 10 I pick the CONSTANT (unless the string is "really sexy and smart, verified").

We don't have such a solid choice in YAML. If we want to use a parameter used elsewhere, we need to trust name is somehow validated (it isn't, because exception will tell you anyway).

For example, how do you ignore files in ECS?

    # or
    # or

None of them :(. It's exclude_files! It's painful to look for such bugs because you need to analyze the whole project every time the config is changed.

In PHP, we can do this:


Start Today, Time passes Anyway

Do you need more real-life examples to try it yourself? Learn from merged pull-requests:

And of course, don't do it manually. Use automated tools:

Happy coding!