Как мне получить контейнер PHP DI?
Как загрузить контейнер базы данных с помощью PHP DI? Это один из вариантов, которые я пробовал до сих пор.
settings.php
<?php
use MyApp\Core\Database;
use MyApp\Models\SystemUser;
return [
'Database' => new Database(),
'SystemUser' => new SystemUser()
];
init.php
$containerBuilder = new \DI\ContainerBuilder();
$containerBuilder->addDefinitions('Settings.php');
$container = $containerBuilder->build();
SystemUserDetails.php
<?php
namespace MyApp\Models\SystemUser;
use MyApp\Core\Database;
use MyApp\Core\Config;
use MyApp\Helpers\Session;
/**
*
* System User Details Class
*
*/
class SystemUserDetails
{
/*=================================
= Variables =
=================================*/
private $db;
/*===============================
= Methods =
================================*/
/**
*
* Construct
*
*/
public function __construct(Database $db)
{
# Get database instance
// $this->db = Database::getInstance();
$this->db = $db;
}
/**
Слишком мало аргументов для функции MyApp\Models\SystemUser\SystemUserDetails::__construct(), 0 передано в /www/myapp/models/SystemUser.php в строке 54 и ровно 1 ожидаемый файл: /www/myapp/models/SystemUser/SystemUserDetails.php
Разве база данных не должна загружаться автоматически?
Трассировка:
Сейчас мой главный
index.php
файл расширяетсяinit.php
это файл, в котором создается контейнер (вставленная часть кода в пост).Тогда я называю
App
класс, который выбирает URL(mysite.com/login/user_login) и создает новый класс контроллера и запускает упомянутый метод, в данном случае это первая страница -MyApp/Contollers/Login.php
,user_login
Метод выбирает учетные данные, проверяет их и, если они действительны, использует объект SystemUser для входа в систему.
Класс SystemUser:
namespace MyApp\Models;
class SystemUser
{
public $id;
# @obj SystemUser profile information (fullname, email, last_login, profile picture, etc')
protected $systemUserDetatils;
public function __construct($systemUserId = NULL)
{
# Create systemUserDedatils obj
$this->systemUserDetatils = new \MyApp\Models\SystemUser\SystemUserDetails();
# If system_user passed
if ( $systemUserId ) {
# Set system user ID
$this->id = $systemUserId;
# Get SysUser data
$this->systemUserDetatils->get($this);
} else {
# Check for sysUser id in the session:
$systemUserId = $this->systemUserDetatils->getUserFromSession();
# Get user data from session
if ( $systemUserId ) {
# Set system user ID
$this->id = $systemUserId;
# Get SysUser data
$this->systemUserDetatils->get($this);
}
}
}
}
1 ответ
PHP-DI работает правильно.
В вашем SystemUser
класс вы делаете:
$this->systemUserDetatils = new \MyApp\Models\SystemUser\SystemUserDetails();
Конструктор для SystemUserDetails
требует Database
объект, который вы не передаете.
По телефону new
напрямую, вы не используете PHP-DI. Делая это, вы скрываете зависимость, а это именно то, чего вы якобы пытаетесь избежать, если хотите использовать систему внедрения зависимостей.
Если SystemUser
зависит ("потребности") SystemUserDetails
, зависимость должна быть явной (например, объявленной в ее конструкторе).
Более того: Вам не нужен файл определений для такой системы. И файл определений, который вы показываете в своем вопросе, не соответствует рекомендациям, рекомендованным PHP-DI.
Ваш дизайн далек от совершенства, и я не уверен в ваших конечных целях, но если вы сделали что-то подобное, это может сработать:
<?php
// src/Database.php
class Database {
public function getDb() : string {
return 'veryDb';
}
}
<?php
// src/SystemUserDetails.php
class SystemUserDetails {
protected $db;
public function __construct(Database $db)
{
$this->db = $db;
}
public function getDetails() {
return "Got details using " . $this->db->getDb() . '.';
}
}
<?php
// src/SystemUser.php
class SystemUser {
protected $details;
public function __construct(SystemUserDetails $details, $userId=null) {
$this->details = $details;
}
public function getUser() {
return "Found User. " .$this->details->getDetails();
}
}
<?php
//init.php
require_once('vendor/autoload.php');
// build the container. notice I do not use a definition file.
$containerBuilder = new \DI\ContainerBuilder();
$container = $containerBuilder->build();
// get SystemUser instance from the container.
$userInstance = $container->get('SystemUser');
echo $userInstance->getUser(), "\n";
Что приводит к:
Found User. Got details using veryDb.