对于Web MVC中的php-di容器,我为路由器准备了以下定义:
return [
'router' => function (ContainerInterface $c) {
//...
return new Router(...);
}
];
现在我想映射一个接口(
MyLib\Routing\RouterInterface
)执行
'router'
条目。在php-di文档中,我发现了三种实现这一点的方法。像这样:
-
RouterInterface::class => DI\create('router')
-
RouterInterface::class => DI\autowire('router')
-
RouterInterface::class => DI\get('router')
当我应用第3个选项时,所有选项都正常,例如,我可以使用以下命令检索接口条目:
$router = $container->get(RouterInterface::class);
var_dump($router);
但是,当我尝试前两个选项时,我收到了错误:
(1/1) InvalidDefinition
Entry "MyLib\Routing\RouterInterface" cannot be resolved: the class doesn't exist
Full definition:
Object (
class = #UNKNOWN# router
lazy = false
)
所以我想问一下:你能给我解释一下,在这个案例中,这三个选项有什么区别吗?
谢谢你
完成接受的回答:
@matthieunapoli的答案是正确的。我会根据我做的测试得出以下结论(见下文)。
结论:
帮助程序的功能
create()
和
autowire()
不要以任何方式引用容器中的条目。它们接收一个类名作为参数,并确保该类的对象是
新的
创建(一次)。即使现有容器定义的名称与类名相同,并且该条目已经创建了相同类型的对象,也会发生这种情况。
仅辅助函数
get()
引用容器条目,而不是类名(如Matthieu所示)。
测试:
1)我定义了以下类别:
<?php
namespace Test;
class MyTestClass {
public function __construct($input = NULL) {
if (empty($input)) {
$input = 'NO INPUT';
}
echo 'Hello from MyTestClass. Input is: ' . $input . '<br/>';
}
}
2)我定义了以下容器条目:
return [
'Test\MyTestClass' => function (ContainerInterface $c) {
return new Test\MyTestClass('12345');
},
'my.test.entry.for.create' => DI\create('Test\MyTestClass'),
'my.test.entry.for.autowire' => DI\autowire('Test\MyTestClass'),
'my.test.entry.for.get' => DI\get('Test\MyTestClass'),
];
3)我执行了以下代码:
<?php
$myTestEntryFor_MyTestClass = $container->get('Test\MyTestClass');
$myTestEntryFor_Create = $container->get('my.test.entry.for.create');
$myTestEntryFor_Autowire = $container->get('my.test.entry.for.autowire');
/*
* This prints nothing, because an object of type "MyTestClass" was
* already created by the container definition "'Test\MyTestClass'".
*/
$myTestEntryFor_Get = $container->get('my.test.entry.for.get');
4)我收到以下结果:
Hello from MyTestClass. Input is: 12345
Hello from MyTestClass. Input is: NO INPUT
Hello from MyTestClass. Input is: NO INPUT