【问题标题】:How to rewrite a container base class in symfony 3.2如何在 symfony 3.2 中重写容器基类
【发布时间】:2018-09-12 00:05:20
【问题描述】:

我使用 symfony 3.2。我想重写app/AppKernel#getContainerBaseClass。实际上我想重写Container 并创建我自己的,它从Symfony\Component\DependencyInjection\Container 扩展而来。

我发现AppKernel#getContainerBaseClass,据我所知返回容器类。我尝试了以下方法:

protected function getContainerBaseClass() {
    if ('test' == $this->environment) {
        return \AppBundle\DependencyInjection\TestContainer::class;
    }

    return parent::getContainerBaseClass();
}

而且它不起作用。我怎么知道它不起作用。首先,我检查容器是否不会从自定义容器中运行。其次,我在提到的方法中设置了断点,它没有被调用。但是调用了AppKernel#getRootDirAppKernel#getCacheDir 中的断点。我在Kernel 中搜索了一些有用的东西。但很难理解为什么它不起作用。我试图清除缓存。

在我看来,我做错了什么。但是互联网对重写 symfony 容器一无所知。很奇怪。

我想重写容器以允许更改(模拟)配置。目前据我所知 symfony 有一个无法更改的参数包。

【问题讨论】:

  • 出于好奇:需要重写容器吗?
  • @ccKep 更新 Q
  • 相关方法应该是基类Kernel中的getContainerClass(不仅仅是getContainerBaseClass)和initializeContainerLines 452 - 501 in Kernel.php供参考。
  • 一般不明白为什么它们是相关的。 getContainerClass 是在缓存中工作的类。考虑$class = $this->getContainerClass(); $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);。在initializeContainer我基本上只能装饰容器,但也有限。
  • 内核在boot() 中调用initializeContainer(),而后者又从getContainerClass() 而不是getContainerBaseClass() 中获取容器类名称。之后是$this->container = new $class();

标签: symfony


【解决方案1】:

所以要了解答案的工作原理以及它是否适合您 - 几个 cmets。

有两个类与容器相关。首先,容器本身:Symfony\Component\DependencyInjection\Container。每个环境都不会更改它,它包含没有实际数据的动态方法(没有参数、服务,只是调用来获取它)。二是捆绑容器。它包含所有参数和服务。它解析 yml 文件并从中生成方法/属性。它包含比Symfony\Component\DependencyInjection\Container 更多的方法。例如它有#getDefaultParameters,它返回一个数组中的所有参数。它还有 #getTwigService ,它实际上是 twig 实例。所以它将 yml 文件转换为 php 道具和方法。这捆绑容器类名称和命名空间取决于 env。所以对于测试环境,它是\appTestDebugProjectContainer。由于它是编译的并且与 env 不同,它位于缓存文件夹中。最后一件事:它是从Symfony\Component\DependencyInjection\Container 扩展而来的。

此外,编译后的容器还有一些覆盖Symfony\Component\DependencyInjection\Container(例如#getParameter)的动态方法。

所以现在我们可以回到这个问题。 AppKernel 有以下与容器相关的方法:

  • getContainerBaseClass 返回源容器。默认为Symfony\Component\DependencyInjection\Container。您可以更改它以使其返回您的自定义容器。但实际上你可以自定义的并不多,因为 bundles 容器重写了很多方法并添加了自己的逻辑。
  • getContainerClass 返回包容器类名。这是重点。它是您的环境中实际使用的容器。你可以扩展它。但首先你应该知道从哪个类扩展。对于我的测试环境,它是appTestDebugProjectContainer。您可以从以下逻辑中获得满足您需要的课程:

    return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';

$this->name 通常是app。其他事情非常简单。 - initializeContainer 它完成所有获取和启动容器的操作。我们感兴趣的行是$this->container = new $class();。我们应该用我们的

重写$class var

那么最终的解决方案是什么。在某处创建您自己的容器并从捆绑的容器名称扩展它。在 AppKernel 中重写 #initializeContainer

test env continer 的例子是。

  1. 创建容器:

```

命名空间 AppBundle\DependencyInjection;

类 TestContainer 扩展 \appTestDebugProjectContainer {

public $fakeParams = [];

public function getParameter($name) {
    $fake = @$this->fakeParams[$name];
    if ($fake) return $fake;
    return parent::getParameter($name);
}

}

```

  1. 在 AppKernel 中重写 #getContainerClass

``` 类 AppKernel 扩展内核 { // ... 受保护的函数初始化容器() { $class= $this->getContainerClass(); $cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug); $新鲜=真;

    if (!$cache->isFresh()) {
        $container = $this->buildContainer();
        $container->compile();
        $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());

        $fresh = false;
    }

    require_once $cache->getPath();
    if ('test' == $this->environment) {
        $class = \AppBundle\DependencyInjection\TestContainer::class;
    }


    $this->container = new $class();
    $this->container->set('kernel', $this);

    if (!$fresh && $this->container->has('cache_warmer')) {
        $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
    }
}
}

```

我只插入了以下几行:

if ('test' == $this->environment) {
            $class = \AppBundle\DependencyInjection\TestContainer::class;
        }

其他所有内容都是从Kernel#initializeContainer复制而来的。

这对我有用。

要查看可以扩展的内容,您可以检查位于(用于测试环境)var/cache/test/appTestDebugProjectContainer.php 中的捆绑容器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多