5

有没有办法从编译器传递中访问内核?我试过这个:

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

这会引发错误。还有另一种方法吗?

4

2 回答 2

13

据我所知,默认情况下,内核在 CompilerPass 中的任何地方都不可用。

但是您可以通过以下方式添加它:

在您的 AppKernel 中,将 $this 传递给编译器传递所在的包。

  • 将构造函数添加到您的 Bundle 对象,该对象接受 Kernel 作为参数并将其存储为属性。
  • 在您的 Bundle::build() 函数中,将内核传递给您的 CompilerPass 实例。
  • 在您的 CompilerPass 中,在构造函数中接受内核作为参数并将其存储为属性。
  • 然后你可以在你的编译器传递中使用 $this->kernel 。

// 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
}
于 2012-12-13T04:09:44.230 回答
10

如果您需要整个内核,则 samanime 推荐的方法有效。

如果你只是对内核包含的一些值感兴趣,那么只使用 symfony 设置的参数就足够了。

以下是可用的列表:

Array
(
    [0] => kernel.root_dir
    [1] => kernel.environment
    [2] => kernel.debug
    [3] => kernel.name
    [4] => kernel.cache_dir
    [5] => kernel.logs_dir
    [6] => kernel.bundles
    [7] => kernel.charset
    [8] => kernel.container_class
    [9] => kernel.secret
    [10] => kernel.http_method_override
    [11] => kernel.trusted_hosts
    [12] => kernel.trusted_proxies
    [13] => kernel.default_locale
)

例如,kernel.bundles包含所有已注册捆绑包的列表,格式为[bundle => class]

PS:我使用以下编译器传递获取此列表:

<?php
namespace Acme\InfoBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class InfoCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        print_r(array_values(array_filter(
            array_keys($container->getParameterBag()->all()), 
            function ($e) {
                return strpos($e, 'kernel') === 0;
            }
        )));
        die;
    }
}
于 2014-09-25T08:41:15.537 回答