Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将依赖项注入容器传递给静态方法_Php_Symfony - Fatal编程技术网

Php 将依赖项注入容器传递给静态方法

Php 将依赖项注入容器传递给静态方法,php,symfony,Php,Symfony,我有一些遗留类。 许多类都是使用工厂类实例化的 还有一个单身班 将来我想用DIC完全取代它们。 目前,要做到这一点,代码库太大了 现在,我的目标是将DI容器注入到Singleton类实例化的每个服务中。 Singleton类有一个带有此签名的静态方法 final class Singleton { private static $singletonCache = array(); public static function getInstance($namespace, $class

我有一些遗留类。 许多类都是使用工厂类实例化的

还有一个单身班

将来我想用DIC完全取代它们。 目前,要做到这一点,代码库太大了

现在,我的目标是将DI容器注入到Singleton类实例化的每个服务中。 Singleton类有一个带有此签名的静态方法

final class Singleton
{
  private static $singletonCache = array();

  public static function getInstance($namespace, $className)
  {
  }
}
在此函数中,我要检查:

$instance = new $className();

if($instance instanceof ContainerAwareInterface)
{
  // TODO: how do we get the container here
  $instance->setContainer($container);
}

但是,如何才能最好地将容器放在我的“singleton类”(仅静态调用)中?

在引导代码的早期,但在容器实例化之后,您可以将容器传递给singleton类:

Singleton::setContainer($container);
它将容器存储在静态属性中:

final类单例
{
// ...
私人静态容器;
公共静态函数setContainer(ContainerInterface$container)
{
self::$container=$container;
}
}

然而正如您在单例类示例中了解到的,全局状态给您带来的一切都是头痛。传递容器(并使用ContainerWare)是需要避免的。通过将容器传递给您的服务,您使它们依赖于整个服务世界。只传递您实际需要的协作者会更干净。它也更容易测试

另一种方法是在需要时全局访问容器:

public static function getInstance($namespace, $className)
{
  $container = $_GLOBAL['kernel']->getContainer();
}

当然,这种方法有很多问题,但只要你正在过渡,就足够了。

中给出了另一种解决方案,这与这个问题的另一个答案几乎相同,只需使用
global
关键字而不是
$\u global
数组来访问内核对象

public static function getInstance($namespace, $className)
{
  global $kernel;
  $container = $kernel->getContainer();
}

var_dump($instance)并检查您得到的是什么。这是伪代码。我知道我会得到什么。我的问题是$container在静态方法“getInstance”的上下文中不可用。如何从全局作用域注入它?`$instance->setContainer($container);`在这里,通过传递参数
$container
调用方法
setContainer
,问问自己,在使用之前从哪里获得它?我知道最佳实践。但是现在我必须保留遗留类,因为有些客户依赖它们。我无法控制代码库,所以我必须保留BC。这有点难以解释,但我将在以后重构并删除整个类。近两年后,我可以说:这一切都很顺利。我添加了带有适当依赖注入的Symfony DiC。然后我编写了一个“facade”容器::get($id)Container::getParam($key)。用它替换了我代码中所有愚蠢的实例化。容器类用于抛出弃用并将其记录到Kibana。后来我删除了这个糟糕的代码:-)很好。谢谢。这很危险,因为它还允许其他人从$\u GLOBAL访问容器。在你试图清理的代码库中,你不应该打开新的机会来搞砸。不管怎样,全球都是存在的。正是Symfony的设计方式。这取决于开发人员是否滥用它。我的问题是有很多狗屎。。。我试着先把东西放到容器中,然后使用服务容器的全局状态。然后我开始反对全局使用,并开始将部件重构为适当的DI。到目前为止,我喜欢这种方法,我几乎已经完成了应用程序的重构。