Symfony DI:Uncaught ArgumentCountError:函数App::__construct()的



我正在尝试实现Symfonys依赖项注入容器。

我设置了两个容器,一个用于数据库,另一个用于系统用户。

并且我将addArgument()用于App类和SystemUser类,将SystemUser对象推送到App类,并且对于SystemUser类推送Database对象。

index.php:

require_once 'vendor/autoload.php';
use TestingDIApp;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentDependencyInjectionReference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', 'TestingDIDatabase');
$containerBuilder->register('system.user', 'TestingDISystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', 'TestingDIApp')
->addArgument(new Reference('system.user'));

$database       = $containerBuilder->get('database');
$systemUser     = $containerBuilder->get('system.user');
$app            = $containerBuilder->get('app');
# Initialize App class
$app = new App();

App.php:

<?php 
namespace TestingDI;
use TestingDISystemUser; 

class App {
public $systemUser; 
public function __construct(SystemUser $systemUser)
{
var_dump($systemUser);
}
}

我确实看到了我的var_dump结果和对象,但一直收到这个错误:

PHP致命错误:Uncaught ArgumentCountError:函数TestingDI\App::__construct()的参数太少,在第28行的/www/protot/symfony di/index.PHP中传递了0,在/www/pottot/symfony di/TestingDI/App.PHP:12中正好需要1

堆栈跟踪:

0/www/potato/symfony di/index.php(28):TestingDI\App->__construct()

1{main}在第12行的/www/protot/symfony di/testingdi/App.php中抛出

这些是我的其他类:

SystemUser.php

<?php 
namespace TestingDI;
use TestingDIDatabase;
class SystemUser {
public $db; 
public function __construct( Database $database )
{
$this->db = $database;
}
}

数据库.php

<?php 
namespace TestingDI;
class Database {
public function __construct()
{
}
}

对于什么是依赖注入以及如何使用它,似乎有一个基本的误解

由于您使用依赖容器来构建应用程序的不同部分,因此应该从容器中获取这些对象,而不是直接实例化它们。

而且,如果要直接实例化它们(例如new App()),则需要遵守常规语言规则。在这种情况下,构造函数的签名:

public function __construct(SystemUser $systemUser)

如果您调用构造函数而不将SystemUser类的对象传递给它,它将失败,就像您以不符合其签名的方式调用它时任何其他方法/函数都将失败一样。

当你做的时候

$app            = $containerBuilder->get('app');

您的应用程序已经"初始化",您根本不需要调用new

这样做:

$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', 'TestingDIDatabase');
$containerBuilder->register('system.user', 'TestingDISystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', 'TestingDIApp')
->addArgument(new Reference('system.user'));

$database       = $containerBuilder->get('database');
$systemUser     = $containerBuilder->get('system.user');
$app            = $containerBuilder->get('app');

你做的相当于:

$database   = new Database();
$systemUser = new SystemUser($database);
$app        = new App($systemUser);

只有你让DI容器为你做这项工作。当然,考虑到容器定义的详细程度,这似乎有点毫无意义。

但你可以让自动布线的力量为你做大部分繁重的工作,并做以下事情:

$container = new ContainerBuilder();
$container->autowire( Database::class );
$container->autowire( SystemUser::class );
$container->autowire( App::class )
->setPublic( true );
$container->compile();
// this will get you an application instance with all the dependencies
// resolved and injected in the class.
$app = $container->get( App::class );

我现在注意到你在尝试不同的DI库时已经遇到了类似的问题,我现在意识到整个问题围绕着一个关于DI容器处理什么问题的简单误解

最新更新