8 News in Config Transformer that Converts Symfony YML to PHP
If you have not switched your Symfony configs from YAML to PHP, there no better time like present.
This month we tested the ConfigTransformer to its limit. It had to deal with edge-cases from Symfony 2.8 all the way through Symfony 3.4. With features that were removed for years. As a result, we added default processing of *.yaml
and .yml
syntax at the same time and support for scalars like ::hi
and 'hello::'
.
That's just the tip of the iceberg. What are the 5 new features you'll be able to enjoy in the upcoming release?
1. New Support for Directory Loader
Since Symfony 2.8, it is possible to load configs from a single directory. That means you can use the shorter syntax...
imports:
- - { resource: packages/doctrine.yml }
- - { resource: packages/framework.yml }
- - { resource: packages/security.yml }
+ - { resource: packages/ }
...with the same effect. Now you won't forget to include the config here. It's pretty rare with legacy projects, but still possible syntax.
In the new ConfigTransformer version, we cover directory loading out of the box ✅
2. New Defaults Extensions Autoloaded
The directory loading opened a complete feature list we can cover. E.g., now it's possible to load extensions from these imported configs:
doctrine:
key: value
We've added the list of 10 default extensions to cover - 'doctrine'
, 'framework'
, 'monolog'
, 'security'
, 'twig'
and more. Including the deprecated ones, e.g. 'assetic'
.
This allows us converting a much lower Symfony version than ever - Symfony 2.8 ✅
3. Added Support for autowiring_types
This option was deprecated in Symfony 3.3. If any config contained it, it was skipped.
It was quite a complex challenge because the code is removed in Symfony 6, and ConfigTransformer is built on that version.
But in the end, we managed to add it:
services:
some_service:
class: App\SomeClass
autowiring_types: App\SomeInterface
↓
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use App\SomeClass;
use App\SomeInterface;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set('some_service', SomeClass::class)
->addAutowiringType(SomeInterface::class);
Now it's covered as expected ✅
4. Add Support for Unquoted Scalars
Unquoted scalars were deprecated in Symfony 3.1. If your config had it, the conversion crashed:
framework:
secret: %secret%
Are you using a Symfony version where this is still valid syntax? We have good news for you.
We added automated pre-quoting of scalar so this can be parsed with ease ✅
5. Skip PHP Configs Loading
Usually, we take many little steps when it comes to huge changes. We don't convert all the files at once, but rather one group at a time, e.g. first parameters, then services, then extensions.
That means in certain point of time, we have part configs in PHP and part in YAML:
/configs
config.yml
/parameters
items.php
Before, the ConfigTransformer tried to load the PHP configs and invoked a bunch of class loading and config interpretation, that could crash.
Now it will skip PHP and focuses solely on the YAML files ✅
6. Informative Output with Beautiful Colored Diff
Do you want first to try it on a single file? That's completely normal. I often do that, too, to verify the output is the same as I expect.
At the moment, we can run a --dry-run
so we see what changes:

We see some files are removed, and other files are added. Okay, but what about content? At this point, the --dry-run
does not change anything, which is correct. But it also doesn't give us any indices to decide to run a command without it. We can do better.
That's why we've redesigned the output to provide the following:
- Information about the file rename
- full diff of what you expect

Beautiful and clear ✅
7. Improved Support for [email protected]
Thanks to Tofandel you can enjoy this impressive feature that handles complex cases of conditional environments:
[email protected]:
web_profiler:
toolbar: true
intercept_redirects: false
framework:
profiler: true
↓
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
if ($containerConfigurator->env() === 'local') {
$containerConfigurator->extension('web_profiler', [
'toolbar' => true,
'intercept_redirects' => false,
]);
$containerConfigurator->extension('framework', [
'profiler' => true
]);
}
};
8. Refactored Constant Support
Last but not least is a feature that focuses on constant. Constants were one of the weakest parts of ConfigTransformer, with a lot of hacking. It was prone to error on non-existing or non-autoloaded constants, which should not happen as the scope of this tool is entirely static.
Again, big thanks to Tofandel, who refactorted it into a smooth solution. It now handles any constant possible:
parameters:
class_constant: !php/const App\SomeConst::TEST
class: !php/const App\SomeConst::class
unexisting_constant: !php/const App\MissingClass::NOT_HERE
another_key: '%env(string:default::CODE_EDITOR)%'
↓
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set('class_constant', App\SomeConst::TEST);
$parameters->set('class', App\SomeConst::class);
$parameters->set('unexisting_constant', App\MissingClass::NOT_HERE);
$parameters->set('another_key', '%env(string:default::CODE_EDITOR)%');
};
As a bonus, it cut down the converting speed on one project from 3 seconds to 200 ms. That's 1500 % faster.
Thank you ✅
Start Now to Save Work
I'm proud of this leap forward and better support for older Symfony versions. It allows to convert configs to a broader range of projects and start using PHP in earlier stages. That brings Rector, ECS, and PHPStan to help as well, as they cover any PHP file, even configs.
Now it's the best time to switch - here is how
Happy coding!
Have you find this post useful? Do you want more?
Follow me on Twitter, RSS or support me on GitHub Sponsors.