Link Search Menu Expand Document
24 Июля 2023 г.

Php di

Содержание

Контейнер занимается инициализацией приложения, собирает объекты и прокидывает их друг в друга. В идеальном контейнере прикладной код должен видеть объекты которые он ждет, а не видеть весь контейнер.

Установка

# Стандартная через composer
composer require php-di/php-di

Базовое использование


// Допустим у нас в системе есть два класса Db и User
class Db
{
    public function createDbConnection(): int
    {
        return 123;
    }
}

class User
{
    public $db;
    public function __construct(Db $db)
    {
        $this->db = $db;
    }
}

// В конструкторе класса User у нас есть зависимость класс db
// Теперь создаем контейнер
$builder = new ContainerBuilder();
$builder->build();
// Так как у нас эти классы доступны прямо здесь
// Мы можем просто получить объект класса User и все его зависимости
$user = $container->get('User');
// Можем пользоваться объектом
$user->db->createDbConnection()

Карта значений

Автоматическое разрешение зависимостей это хорошо, но как нам самим определить список классов.

PHP-di умеет загружать нашу “карту” классов и использовать ее как инструкцию по созданию объектов.

Важным плюсом использования является, то что объекты будут создаваться только тогда, когда они запрашиваются из контейнера.

Посмотрим в каком виде значения можно передавать

<?php

$builder = new \DI\ContainerBuilder();
// Добавляем зависимости
// Но так делать неправильно, так как объявления в таком виде вызываются сразу
$builder->addDefinitions([
    'value' => 'item value',
    'value array' => [
        'one' => [],
        'two' => []
    ],
    'stdClass' => new StdClass(),
]);

$container = $builder->build();
// Использование
$container->get('stdClass')

// Как же все таки нужно определять зависимости
class Test
{
    public function testfunc()
    {
        return __CLASS__;
    }
}

$builder = new \DI\ContainerBuilder();
$builder->addDefinitions([
    // Просто объявляем зависимость, возвращать можем что угодно
    'Test1' => function (\Psr\Container\ContainerInterface $container) {
        return 123;
    },
    // Используем для этого фабрику из DI
    'Test2' => DI\Factory(function (\Psr\Container\ContainerInterface $container) {
        return 657;
    }),

    // Объявляем зависимость
    'TestClass' => function () {
        return new Test();
    },
    // Создаем класс с помощью create
    'Test' => DI\create('Test'),

    // Используем зависимость напрямую
    'Test4' => function(Test $test){
        return $test->testfunc();
    },
    // Используем зависимость через контейнер
    'Test3' => function (\Psr\Container\ContainerInterface $container){
        return $container->get('TestClass')->testfunc();
    },
    // Алиас для теста
    'Test5' => DI\get('Test'),
    // Получаем переменную окружения
    'Test6' => DI\env('APPLICATION_ENVIRONMENT'),
    // Можно вернуть массив объектов созданных из контейнера, например так
    'Test7' => [
        DI\get('Test'),
        DI\get('Test'),
    ]
]);

$container = $builder->build();
// Используем
$container->get('Test7');

Возник вопрос или предложение пиши на почту alexsey_89@bk.ru или в Телеграмм канал

Дата публикации: 24 Июля 2023 г.

Содержание


Наверх

Последнее изменение страницы: 28 Июля 2023 г.