Search code examples
symfonysymfony-http-kernel

Symfony2 - Access kernel from a compiler pass


Is there a way to access the kernel from inside a compiler pass? I've tried this:

    ...
    public function process(ContainerBuilder $container)
    {
        $kernel = $container->get('kernel');
    }
    ...

This throws an error. Is there another way to do it?


Solution

  • As far as I can tell, Kernel isn't available anywhere in a CompilerPass, by default.

    But you can add it in by doing this:

    In your AppKernel, pass $this to the bundle the compiler pass is in.

    • Add a constructor to your Bundle object, which accepts the Kernel as a parameter and stores it as a property.
    • In your Bundle::build() function, pass the Kernel to your CompilerPass instance.
    • In your CompilerPass, at a constructor to accept the Kernel as a parameter and store it as a property.
    • Then you can use $this->kernel in your compiler pass.

    // app/AppKernel.php
    new My\Bundle($this);
    
    // My\Bundle\MyBundle.php
    use Symfony\Component\HttpKernel\KernelInterface;
    
    class MyBundle extends Bundle {
    protected $kernel;
    
    public function __construct(KernelInterface $kernel)
    {
      $this->kernel = $kernel;
    }
    
    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $container->addCompilerPass(new MyCompilerPass($this->kernel));
    }
    
    // My\Bundle\DependencyInjection\MyCompilerPass.php
    use Symfony\Component\HttpKernel\KernelInterface;
    
    class MyCompilerPass implements CompilerPassInterface
    protected $kernel;
    
    public function __construct(KernelInterface $kernel)
    {
       $this->kernel = $kernel;
    }
    
    public function process(ContainerBuilder $container)
    {
        // Do something with $this->kernel
    }