Symfony: Move internal Container configuration from XML to PHP

Created on 10 Jun 2020  路  94Comments  路  Source: symfony/symfony

In Symfony 6, I we will promote usage of configuration written in PHP instead of YAML. For third-party bundles and core, we should do the same, replacing XML with PHP. Doing so would remove the need for the XML lib for core.

The biggest advantage is auto-completion with any modern IDE without explicit support for Symfony, and probably one less thing to learn (how to configure things in YAML/XML).

Be warned that semantic configuration will stay in YAML for now (as using PHP is much harder there).

36778 did the work for the Twig bundle as an example.

We now need help from the community to move all the other bundles:

PLEASE, comment here BEFORE starting to work on something and WAIT for the confirmation to avoid duplicate work.

  • [x] src/Symfony/Bundle/DebugBundle/Resources/config/services.xml (@jschaedl)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml (@magnetik)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/assets.xml (@NguyenTruongLinh)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/cache*.xml (@iamvar)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml (@hvt)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml (@AhmedRaafat14)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/debug*.xml (@TuxBoy)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/error_renderer.xml (@benji07)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml (@tuanminhgp)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/form*.xml (@misekai)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment*.xml (@idetox)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/http*.xml (@IonBazan)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/identity_translator.xml (@smmd)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/lock.xml (@tomasjav)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer*.xml (@instabledesign)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger*.xml (@hyoa)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/mime_type.xml (@GromNaN)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier*.xml (@szepczynski)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml (@hvt)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/property_access.xml (@qneyrat)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml (@qneyrat)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/request.xml (@dangkhoagms)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/routing*.xml (@phamuyentri)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/secrets.xml (@GromNaN)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/security_csrf.xml (@Noweh)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml (@mamontovdmitriy)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml (@rvanlaak)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml (@cocorambo)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/ssi.xml (@50bhan)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml (@GaryPEGEOT)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/translation*.xml (@malteschlueter)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/validator*.xml (@simivar)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/web*.xml (@ck-developer)
  • [x] src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml (@lyrixx)
  • [x] src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml (@JudicaelR)
  • [x] src/Symfony/Bundle/SecurityBundle/Resources/config/console.xml (@JudicaelR)
  • [x] src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml (@JudicaelR)
  • [x] src/Symfony/Bundle/SecurityBundle/Resources/config/security*.xml (@qneyrat)
  • [x] src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.xml (@ck-developer)
  • [x] src/Symfony/Bundle/WebProfilerBundle/Resources/config/*.xml (@jschaedl)
Good first issue Help wanted

Most helpful comment

We've completed this. Great community effort! Thanks everyone 馃憦

All 94 comments

I do something in Notifier Component few weeks ago. I think I can migrate src/Symfony/Bundle/FrameworkBundle/Resources/config/notifier.xml

@szepczynski Great, can you do notifier_transports.xml as well? I've added you name on both :)

yes, i missed them on the list

One question about migrating FrameworkExtension - I guess that we need temporary two loaders, one for not migrated XMLs, and one for migrated until all configuration will be migrated.

Can someone add at first Php Loader to FrameworkExtension that everyone who starting from current master don't need create Php Loader?

I can start with http_client.xml and http_client_debug.xml first 馃槄

@szepczynski Can you create the PHP loader in a separate PR that I can merge fast?
@IonBazan added, thanks

@fabpot ok

For third-party bundles, we should do the same

For third-party bundles, I think it is too early to start this migration. The migration relies on using the new PHP DSL to configure services (migrating to the lower-level PHP API would not make sense as that would make maintenance harder). And this DSL is incomplete in previous versions of Symfony.
As we expect third-party bundles to keep support for our LTS release in a maintained version (otherwise, the LTS becomes useless, if it forces to use unmaintained versions of these bundles), they will either have to maintain 2 versions in parallel (high cost with low benefit as the XML config files will keep working) or delay the migration until the time they can go on supporting Symfony 5.2+ (so near the time 5.4 becomes the active LTS and 6.0 gets released).
The good news is that there is no actual BC impact for bundles to do the migration (they can do it in any minor version). And dropping ext-xml from project requirements will be possible only when all packages are migrated and nothing else needs it (dom-crawler needs it for instance)

I want to help. Can I try to migrate [serializer] or something else?

Let me help. I can start from
src/Symfony/Bundle/FrameworkBundle/Resources/config/cache*.xml

@mamontovdmitriy serializer is yours
@iamvar cache*.xml files are yours
Thank you!

I want to give it a hand. Can I start with
src/Symfony/Bundle/FrameworkBundle/Resources/config/routing/errors.xml

@phamuyentri Sure, can you do routing*.xml?

Hi,
I can do annotations.xml to help :)

@magnetik Thank you, it's yours now.

Hi, I'd like to help with lock component.

I can help with src/Symfony/Bundle/FrameworkBundle/Resources/config/form*.xml
My understanding is they are 3 files, correct me if I'm wrong:

  • src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/form_debug.xml

@misekai Great! Thank you.

@tomasjav Lock is yours, thank you

I can help with Bundle/FrameworkBundle/Resources/config/request.xml

@fabpot I can help with src/Symfony/Bundle/FrameworkBundle/Resources/config/console.xml

@dangkhoagms Thank you
@AhmedRaafat14 Thank you

Hi @fabpot, I think I can help src/Symfony/Bundle/FrameworkBundle/Resources/config/assets.xml

@fabpot I'd like to help with

  • src/Symfony/Bundle/DebugBundle/Resources/config/services.xml and
  • src/Symfony/Bundle/WebProfilerBundle/Resources/config/*.xml

@NguyenTruongLinh assets is yours
@jschaedl wow, that's a lot, thank you.

Hey @fabpot, can I do src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml?

Was wondering about the namespace of the PHP DI file, why is that different of the file's path?

@hvt ok for profiling.
The namespace allows to use the functions directly without use statements. It's more convenient that way.

Hi @fabpot

Can I start with :
src/Symfony/Bundle/SecurityBundle/Resources/config/console.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/collectors.xml

@fabpot, i can help with :

  • src/Symfony/Bundle/FrameworkBundle/Resources/config/property_access.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml

@JudicaelR Cool, thanks for your help
@qneyrat Thank you!

Hi @fabpot ,I can help with:
src/Symfony/Bundle/FrameworkBundle/Resources/config/property_access.xml

@tuanminh1997 Too late :) Can you choose another one?

@fabpot I can help with src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger*.xml

Hi @fabpot, can I do src/Symfony/Bundle/FrameworkBundle/Resources/config/test.xml ?

Hi @fabpot, can i do src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer*.xml ?

Hi @fabpot, can i do src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml

@hyoa @GaryPEGEOT @instabledesign @tuanminh1997 You got your files! Thanks.

Hello, I can do mime_type.xml and secrets.xml.

@GromNaN Done, thank you.

Hello @fabpot, can I do src/Symfony/Bundle/FrameworkBundle/Resources/config/security_csrf.xml

@Noweh sure, that one is for you.

I can do src/Symfony/Bundle/FrameworkBundle/Resources/config/collectors.xml too if that's ok.

Hey @fabpot i can do src/Symfony/Bundle/FrameworkBundle/Resources/config/error_renderer.xml ?

@hvt Sure
@benji07 Yes, done.

Hey, I want to help with src/Symfony/Bundle/FrameworkBundle/Resources/config/identity_translator.xml 馃槂

@smmd It's yours, thank you

Hey @fabpot Can I go for src/Symfony/Bundle/FrameworkBundle/Resources/config/ssi.xml?

@50bhan Sure, go for it.

Hi @fabpot, i think i can help with src/Symfony/Bundle/FrameworkBundle/Resources/config/translation*.xml

Just a warning here that config files that allow arbitrary code execution are a security threat in certain scenarios. Not sure if this will affect drupal for example that allows config imports over a web interface. Although Symfony service definitions are not used for those imports I think.

Mixing data and code is a bad idea in general, see all the security problems because of mixing HTML and JavaScript or the PHP serialization format.

I want to help with src/Symfony/Bundle/FrameworkBundle/Resources/config/validator*.xml.

I want to help with src/Symfony/Bundle/FrameworkBundle/Resources/config/translation*.xml

I can start with src/Symfony/Bundle/FrameworkBundle/Resources/config/debug*.xml

Just a warning here that config files that allow arbitrary code execution are a security threat in certain scenarios. Not sure if this will affect drupal for example that allows config imports over a web interface. Although Symfony service definitions are not used for those imports I think.

Mixing data and code is a bad idea in general, see all the security problems because of mixing HTML and JavaScript or the PHP serialization format.

@klausi I am not sure, I get your point. You can still mix config styles and use e.g. yaml for exposed (editable) configs. This only affects Symfony's internal configuration which you probably should not expose or change during runtime anyway. Even without malicious intent you can likely break your whole application with it. Can you elaborate on what a possible attack scenario could look like?

I want to help with src/Symfony/Bundle/FrameworkBundle/Resources/config/session.xml

Hi @fabpot I want to help with

  • src/Symfony/Bundle/FrameworkBundle/Resources/config/translation*.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/debug*.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/web*.xml
  • src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_twig*.xml

@malteschlueter @simivar @cocorambo You're good to go.
@ck-developer web.xml and templating_twig.xml are yours.

@fabpot here to help! Feel free to give me the one or two that are left.

@rvanlaak If you can do src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml, that would be fantastic.

@fabpot I can do fragment if it is still left

@idetox Yes, it's yours.

@fabpot, i can start security* too

@qneyrat that was the last one, thank you.

@fabpot Is there something available for me?

@mega6382 Thanks for asking. All files are now taken care of now.

Hi!... this is a great move..

Just an FYI here... I checked with 1-2 installations, and I hope I am not wrong.. but this little thing..

image

does not work with PHP files. For those that don't know, when you click that icon you are supposed to navigate to the service declaration file.

Before I could navigate to the service declaration even if it was an internal service of symfony.

Although I should report this error to PHPStorm.. maybe this might get some attention here as well and there is someone that can apply a fix (hopefully if it is not only my problem)

@gmponos Not PHPStorm user, but I think this is already fixed :) https://github.com/Haehnchen/idea-php-symfony2-plugin/pull/1487

Great.. I believe that ppl will be driven by this move and start moving to PHP service files..

Please consider sponsoring @Haehnchen if you like the plugin btw!
https://twitter.com/fabpot/status/1271105586726424576

Cool move :sunglasses: I like it !

I'd like to try it on few packages. Is there some automated script that takes *.yml on the input and dumps the same *.php file? Something like http://converter.rosstuck.com/

Is there some automated script that takes *.yml on the input and dumps the same *.php file?

@TomasVotruba -> https://github.com/symfony/maker-bundle/pull/604 (WIP)

I have quite mixed feelings about this.

On one hand, I am all for not using XML: the php config will be probably more efficient to parse, and there will be one less dependency on running Sf.

On the other hand, I find php config to have extremely poor readability for humans, compared to yaml.

Although having IDE support is good, and the debug commands help as well, I very often find myself looking for a service definition via using the editor's native 'search' function to grep through source code and taking a quick look at the resulting snippet. The php snippets that I can see f.e. in https://github.com/symfony/symfony/pull/36778/files atm make my head spin and take a long time to parse. It might be that it is just a habit that I need to form, but still... easy to understand by humans rates quite high on my engineering priorities.

On the other hand, I find php config to have extremely poor readability for humans, compared to yaml.

Moreover, indenting as it is done could be reverted automatically by many cs-fixer. I'm afraid it may become difficult to maintain such code.

If anyone needs help migrating his files to PHP or won't have time to do that feel free to contact me. I am happy to help :).

We've completed this. Great community effort! Thanks everyone 馃憦

Thank you all for your great work.

these kind of changes are making me go away from symfony after years of usage.

@adsazad Care to explain. Here, it's all about internal changes, it does not change anything for developers.

Me and my team are really worried about where symfony is going. our lots of project are in symfony when symfony 4 came out there were many changes releated with file structure and doctrine's yml. which made updating project very uneasy.

@adsazad The file structure has not changed at all since 4.0. I'm not sure what you are referring to.

@fabpot. pardon if i was unclear.
i mean update between 3.4 and 4.4

So that update was 2 years ago... The update from 4.4 to 5.0 involved no file structure changes and this PR is updating only 100% internal files. I don't think there will be any major changes in the file structure in the coming future (before the 4.0 change, the file structure was the same for 6 years (!).

Please also note that the file structure and config formats are not imposed by Symfony. That's something I love about Symfony, you can do and use whatever you feel like using. It's perfectly fine to use the 3.4 file structure with Symfony 5.0.

@wouterj
I was not really emphasizing only file structure. Don't take this in wrong way but we have started thinking that symfony has started loosing its flexibility.

i just want to say that updating symfony is really hard job.

I don't think you should have that feeling :). I think from a base, Symfony is just as flexible as in the past. However, I agree that one thing changed: The experience when using the default is now much much better by the introduction of Symfony Flex. This hasn't made the other formats worse though, they are still at the same level as when Symfony 2.0 was released.

And to be honest, I think that makes sense. Symfony allows you to get to your destination. When using the paved road, you have a smooth experience to the destination. You can also use the unpaved road, you still get to the destination but the experience is not so smooth. In Symfony 2.0, there was no paved road, in Symfony 4.0+ there is a paved road.

Anyway, yes it was a hard upgrade from the unpaved to the paved road in Symfony 4.0. I think the core team also realizes this. See e.g. this tweet from Fabien (responding to some people that expressed the same feelings as you): https://twitter.com/fabpot/status/1270981253962043392 _"4.0 -> 5.2 is really about new features and refinements but no big changes. I don't envision any revolution in the next few versions either."_

In any case, this is completely off-topic for this issue, as this issue is purely internal.

@adsazad i just want to say that updating symfony is really hard job.

I feel you. I recommend you hire an external upgrade consultant to upgrade it. Doing it manually is hell... and non-sense in 2020. I do around 1 project upgrade a month on average, usually Symfony 3 to 5. With right tools like @rectorphp, coding standard and @phpstan it's piece of cake

this month i did 6 upgrades. i have even developed my own tool for upgrading them.

I just wanted to highlight:

You can also use the unpaved road, you still get to the destination but the experience is not so smooth. In Symfony 2.0, there was no paved road, in Symfony 4.0+ there is a paved road.

I disagree, I used to bend Symfony in all most terrible ways I could think of (starting at 2.8) and it was fine, until 3.4. 3.4 did some great optimizations, and very nice end-user improvements, but it broke some of the natural flexibility it had before. I think it's the natural cost of specialisation and optimisation, nobody can't get around, not even Symfony.

Don't take it wrong, it's not a complaint, I love Symfony and continue gladly to use it, yet in my experience, trying to walk out the paved road since 3.4 may be very difficult, at least compared to how it was very easy and nice before. Especially with debug component, which is really invasive, and a few other performance optimisations that made the code much harder to read, and broke some undocumented edge cases.

FWIW (and sorry for the OT) I agree with the sentiment that the "paved road" comes with a cost. Increasing the magic while keeping the flexibility leads naturally to greater code complexity. This is also often the case for speed optimizations. The end result is a framework which makes a lot of tedious operations quick and easy, but is harder to grasp when you want to tweak/change bits of it.
Maybe it's just me getting old and taking time to learn all the novelties (aka grumpy), but I am a great fan of code which is easy to read and fits in my head.

Here, it's all about internal changes, it does not change anything for developers.

@fabpot Looks like this issue has caused some confusion and some people thought it affects all configuration files.

Also see here: https://www.reddit.com/r/PHP/comments/h93fjc/symfony_will_now_promote_php_over_yaml_and_xml/.

Be warned that semantic configuration will stay in YAML for now (as using PHP is much harder there).

@fabian Can you be more specific? Which parts of configuration will stay in YAML?

I think he's referring to semantic config (the one you parametrize through Configuration class and its ArrayNodse, prototypes, and so on)

@Taluu As in bundles will still be configured in YAML?

@enumag You can cofigure these in php you just have to load them yourself.

// src/Kernel.php
class Kernel extends BaseKernel
{
    use MicroKernelTrait;

    protected function prepareContainer(ContainerBuilder $container)
    {
        parent::prepareContainer($container);

        (require dirname(__DIR__) . '/config/packages/workflow.php')($container);
    }
}
// config/packages/workflow.php
return static function (ContainerBuilder $container) {
    $container->loadFromExtension(
        'framework',
        [
            'workflows' => [
                ChangeEmailWorkflow::NAME => [
                    "type" => "state_machine",
                    "marking_store" => [
                        "type" => "method",
                        "property" => "state",
                    ],
                    "supports" => [Token::class],
                    "initial_marking" => ChangeEmailWorkflow::STATE_PENDING,
                    "places" => [
                        ChangeEmailWorkflow::STATE_PENDING,
                        ChangeEmailWorkflow::STATE_APPROVED,
                        ChangeEmailWorkflow::STATE_VERIFIED,
                    ],
                    "transitions" => [
                        ChangeEmailWorkflow::TRANSITION_APPROVE => [
                            "from" => ChangeEmailWorkflow::STATE_PENDING,
                            "to" => ChangeEmailWorkflow::STATE_APPROVED,
                        ],
                        ChangeEmailWorkflow::TRANSITION_VERIFY => [
                            "from" => ChangeEmailWorkflow::STATE_APPROVED,
                            "to" => ChangeEmailWorkflow::STATE_VERIFIED,
                        ],
                    ],
                ],
            ],
        ]
    );
};
Was this page helpful?
0 / 5 - 0 ratings