Symfony 4 was released on November 30th.
Update now to the best Symfony ever!

New in Symfony 3.4: Defining compiler passes in the kernel

Contributed by
Nicolas Grekas
in #24257.

In Symfony 3.4, the application kernel can subscribe to events just by implementing EventSubscriberInterface and adding the methods to handle the events. Given that Symfony 4 will push bundle-less applications, in Symfony 3.4 we improved the application kernel to also allow defining compiler passes in it.

To do so, the kernel must implement CompilerPassInterface and include a method called process() where the compiler pass logic is defined:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// src/Kernel.php
namespace App;

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;

class Kernel extends BaseKernel implements CompilerPassInterface
{
    use MicroKernelTrait;

    // ...

    public function process(ContainerBuilder $container)
    {
        // define here the code to manipulate the service container...

        // For example, change some container service:
        $container->getDefinition('app.some_private_service')->setPublic(true);

        // or process tagged services:
        foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
            // ...
        }
    }
}

The compiler pass defined in the kernel is of type PassConfig::TYPE_BEFORE_OPTIMIZATION and has a priority of -10000.

Comments

Why should we use this instead of https://github.com/symfony/symfony/blob/v3.3.9/src/Symfony/Component/HttpKernel/Kernel.php#L503 ?
This process() method is typically called after all bundles loaded their config and ran their own compiler passes. This means this give the opportunity to *alter* any service definition. A practical example would be in the "test" environment, to turn some private services to public, so that they can be mocked in test cases.

Of course, this should be used only when access to the fully configured container is required (like all compiler passes). For more common needs, the configuration should be done as usual.
Oh I see it now, thank you !

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.