New in Symfony 3.3: Kernel Build Method

Contributed by
Iltar van der Berg
in #20107.

The bundle system has been an integral part of the Symfony framework since day one. However, some developers prefer to not use bundles in their applications except Symfony's built-in bundles and third-party bundles.

In Symfony 3.3 we've decided to simplify this by adding a new build() method to the Kernel class. This method allows to register compiler passes and manipulate the container during the building process. That's why this method makes it easy to avoid using any bundle, even the default AppBundle.

Consider the following initial situation where you enable some compiler passes in your AppBundle and then define a bundle extension to load some configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// src/AppBundle.php
class AppBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new SomeCompilerPass());
        $container->addCompilerPass(new AnotherCompilerPass());
        $container->addCompilerPass(new YetAnotherCompilerPass());
    }
}

// src/AppBundle/DependencyInjection/AppExtension.php
class AppExtension extends Extension
{
    public function load(array $config, ContainerBuilder $container)
    {
        $binary = ExecutableResolver::getPath($container->getParameter('kernel.root_dir').'/../');
        $snappyConfig = ['pdf' => ['binary' => realpath($binary)]];

        $container->prependExtensionConfig('knp_snappy', $snappyConfig);
    }
}

In Symfony 3.3, you can remove the AppBundle entirely and define instead this build() method in your AppKernel class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// app/AppKernel.php
class AppKernel extends Kernel
{
    protected function build(ContainerBuilder $container)
    {
        $binary = ExecutableResolver::getPath($container->getParameter('kernel.root_dir').'/../');
        $snappyConfig = ['pdf' => ['binary' => realpath($binary)]];

        $container->prependExtensionConfig('knp_snappy', $snappyConfig);
        $container->addCompilerPass(new SomeCompilerPass());
        $container->addCompilerPass(new AnotherCompilerPass());
        $container->addCompilerPass(new YetAnotherCompilerPass());
    }
}

Comments

What's the gain? i can't see the advantage of this
@Amine not having to create any bundle in your application (some developers prefer that).
Why not. Agree. 👍
Can't see this being a major feature, but will be so useful for people using the microkernel trait 👍
Zander, actually this is useful for everyone that doesn't want to have a bundle in their SRC directory. A bundle should be something re-usable. Right now a bundle is primarily used as easy way to get entities, controllers and commands registered.

This feature is primarily useful when you want to modify certain 3rd party bundle services can be only done _after_ their extension is loaded.

https://stovepipe.systems/post/what-are-bundles-in-symfony
The value is made clear in the post, it makes it easy to build a bundleless application. This is particularly useful for anyone that has a Symfony based application that only uses one application bundle. At the same time it doesn't exclude you from using vendor bundles. Nice.
But its a very small gain over a single psr-4 autoloader line to drop the appbundle folder in src. Being able to do the same thing multiple ways usually ends up with mixed feelings at some point in time, but we'll see

Comments are closed.

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