问题
当我试图在PHP-DI容器中设置一个新值时,我收到了来自PHPStorm的意外警告。
给定以下代码:
function inject(PsrContainerContainerInterface $container){
$container->set(RandomClass::class, new RandomClass());
}
$container = new DIContainer(); class is instantiated
inject($container);
触发以下警告
潜在的多态调用。在其层次结构中没有成员
我理解警告的含义,但我不明白它为什么会弹出,特别是因为我在谷歌和SO上搜索时没有发现任何这种情况,文档也没有提到它。
是我遗漏了什么,还是这是一个";假阳性"?
set()
方法不是PsrContainerContainerInterface
的一部分。
如果您想使用该方法,则不能针对接口键入hint,因为您的代码明确需要PHP-DI实例。
你的代码不一定是通用的,不要想太多。PSR主要适用于框架和库(需要与多个容器兼容(,而不适用于最终用户。
在切换容器库的那一天,您将有许多比替换set()
调用更复杂的事情要做。
问题背后的原因
给定以下代码(与我使用的代码非常相似(
function inject(PsrContainerContainerInterface $container){
$container->set(RandomClass::class, new RandomClass());
}
$container = new DIContainer(); class is instantiated
inject($container);
$container->set(...)
调用将触发以下警告
潜在的多态调用。在其层次结构中没有成员
这是预期的,因为PsrContainerContainerInterface
只包含以下方法的定义
get($id)
has($id)
解决方案
这个问题的两种可能的解决方案:
- 直接用容器键入方法,确保不使用类的FQN,而只使用
Container
和";使用名称空间";,这将使更改为新的容器包变得更容易(因为这仍然是PSR的目标,能够几乎热交换包( - 创建一个基于
PsrContainerContainerInterface
的自定义接口,并向其中添加所需的方法
或者,最终,您可以尝试使PHP-FIG扩展PSR-11标准,以包括标准set($id, $value)
方法。