2

问题

当我尝试在 PHP-DI 容器中设置新值时,我收到了来自 PHPStorm 的意外警告。

给定以下代码:

function inject(Psr\Container\ContainerInterface $container){
    $container->set(RandomClass::class, new RandomClass());
}

$container = new DI\Container(); class is instantiated

inject($container);

触发以下警告

潜在的多态调用。在其层次结构中没有成员

我理解警告的含义,但我不明白它为什么会弹出,特别是因为我在查看 Google 和 SO 时没有发现任何这种情况,并且文档没有提到它。

是否有我遗漏的东西,或者这是“误报”?

4

2 回答 2

0

set()方法不是Psr\Container\ContainerInterface.

如果您想使用该方法,则不能对接口进行类型提示,因为您的代码明确需要 PHP-DI 实例。

你的代码不必是通用的,不要想太多。PSR 主要用于框架和库(需要与多个容器兼容),而不是最终用户。

在您切换容器库的那一天,您将有更多复杂的事情要做,而不仅仅是替换set()调用。

于 2020-08-26T11:47:34.220 回答
0

问题背后的原因

给定以下代码(与我使用的非常相似)

function inject(Psr\Container\ContainerInterface $container){
    $container->set(RandomClass::class, new RandomClass());
}

$container = new DI\Container(); class is instantiated

inject($container);

$container->set(...)调用将触发以下警告

潜在的多态调用。在其层次结构中没有成员

这是意料之中的,因为Psr\Container\ContainerInterface仅包含以下方法的定义

  • get($id)
  • has($id)

解决方案

此问题的两种可能解决方案:

  • 直接用容器键入方法,确保不使用类的 FQN,而只使用Container和“使用命名空间”,这将更容易更改为新的容器包(因为这仍然是 PSR 背后的目标,能够到几乎热插拔包)。
  • 创建一个基于它的自定义接口Psr\Container\ContainerInterface并向其添加所需的方法。

或者,最终,您可以尝试使PHP-FIG扩展PSR-11标准以包含标准set($id, $value)方法。

于 2020-08-26T06:47:13.737 回答