Как мне получить контейнер PHP DI? - PullRequest
0 голосов
/ 13 января 2019

Как загрузить контейнер базы данных, используя 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

Разве база данных не должна загружаться автоматически?

Трассировка:

  1. В настоящее время мой основной index.php файл расширяется init.php, который является файлом, в котором он создает контейнер (вставленная часть кода в сообщение).

  2. Затем я вызываю класс App, который выбирает URL (mysite.com/login/user_login), создает экземпляр нового класса контроллера и запускает упомянутый метод, в данном случае это первая страница - MyApp/Contollers/Login.php.

    1. Метод 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 Ответ

0 голосов
/ 13 января 2019

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.
...