Symfony DI: Uncaught ArgumentCountError: Too few arguments to function App::__construct(), 0 passed in index.php on line 28 and exactly 1 expected
Symfony DI: Uncaught ArgumentCountError: Too few arguments to function App::__construct(), 0 passed in index.php on line 28 and exactly 1 expected
我正在尝试实现 Symfonys 依赖注入容器。
我设置了 2 个容器,一个用于数据库,一个用于系统用户。
并且我正在对 App
class 和 SystemUser
class 使用 addArgument()
,推送到 App
class 一个 SystemUser
对象,对于 SystemUser
class 一个 Database
对象。
index.php:
require_once 'vendor/autoload.php';
use TestingDI\App;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');
$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', '\TestingDI\App')
->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 TestingDI\SystemUser;
class App {
public $systemUser;
public function __construct(SystemUser $systemUser)
{
var_dump($systemUser);
}
}
我确实看到了我的 var_dump 结果和对象,但不断收到此错误:
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function TestingDI\App::__construct(), 0 passed in /www/potato/symfony-di/index.php on line 28 and exactly 1 expected in /www/potato/symfony-di/testingdi/App.php:12
Stack trace:
0 /www/potato/symfony-di/index.php(28): TestingDI\App->__construct()
1 {main}
thrown in /www/potato/symfony-di/testingdi/App.php on line 12
这些是我的其他 classes:
SystemUser.php
<?php
namespace TestingDI;
use TestingDI\Database;
class SystemUser {
public $db;
public function __construct( Database $database )
{
$this->db = $database;
}
}
Database.php
<?php
namespace TestingDI;
class Database {
public function __construct()
{
}
}
似乎对什么是依赖注入以及如何使用它存在基本的误解。
由于您使用依赖容器来构建应用程序的不同部分,因此您应该从容器获取这些对象,而不是直接实例化它们。
而且,如果您要直接实例化它们(例如 new App()
),您需要遵守常规语言规则。在这种情况下,构造函数的签名:
public function __construct(SystemUser $systemUser)
如果你调用构造函数而不向它传递 SystemUser
class 的对象,它将失败,同样地,如果你调用它,任何其他 method/function 都会失败一种不符合其签名的方式。
到你做的时候
$app = $containerBuilder->get('app');
您的应用已经 "initialized",您根本不需要调用 new
。
通过这样做:
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');
$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', '\TestingDI\App')
->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 容器为您完成工作。当然,考虑到您的容器定义冗长,这似乎有点毫无意义。
但您可以让 autowiring 的力量为您完成大部分繁重的工作,并执行以下操作:
$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 容器处理什么问题的简单误解
我正在尝试实现 Symfonys 依赖注入容器。
我设置了 2 个容器,一个用于数据库,一个用于系统用户。
并且我正在对 App
class 和 SystemUser
class 使用 addArgument()
,推送到 App
class 一个 SystemUser
对象,对于 SystemUser
class 一个 Database
对象。
index.php:
require_once 'vendor/autoload.php';
use TestingDI\App;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');
$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', '\TestingDI\App')
->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 TestingDI\SystemUser;
class App {
public $systemUser;
public function __construct(SystemUser $systemUser)
{
var_dump($systemUser);
}
}
我确实看到了我的 var_dump 结果和对象,但不断收到此错误:
PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function TestingDI\App::__construct(), 0 passed in /www/potato/symfony-di/index.php on line 28 and exactly 1 expected in /www/potato/symfony-di/testingdi/App.php:12
Stack trace:
0 /www/potato/symfony-di/index.php(28): TestingDI\App->__construct()
1 {main} thrown in /www/potato/symfony-di/testingdi/App.php on line 12
这些是我的其他 classes:
SystemUser.php
<?php
namespace TestingDI;
use TestingDI\Database;
class SystemUser {
public $db;
public function __construct( Database $database )
{
$this->db = $database;
}
}
Database.php
<?php
namespace TestingDI;
class Database {
public function __construct()
{
}
}
似乎对什么是依赖注入以及如何使用它存在基本的误解。
由于您使用依赖容器来构建应用程序的不同部分,因此您应该从容器获取这些对象,而不是直接实例化它们。
而且,如果您要直接实例化它们(例如 new App()
),您需要遵守常规语言规则。在这种情况下,构造函数的签名:
public function __construct(SystemUser $systemUser)
如果你调用构造函数而不向它传递 SystemUser
class 的对象,它将失败,同样地,如果你调用它,任何其他 method/function 都会失败一种不符合其签名的方式。
到你做的时候
$app = $containerBuilder->get('app');
您的应用已经 "initialized",您根本不需要调用 new
。
通过这样做:
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');
$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('app', '\TestingDI\App')
->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 容器为您完成工作。当然,考虑到您的容器定义冗长,这似乎有点毫无意义。
但您可以让 autowiring 的力量为您完成大部分繁重的工作,并执行以下操作:
$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 );
我现在注意到你在