PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Работа с DI-контейнером на Framework Foton

    Работа с DI-контейнером на Framework Foton

    Аватар автора Работа с DI-контейнером на Framework Foton

    Константин

    Иконка календаря07 октября 2026
    di-контейнерframework FotonFotonmiddleИконка уровня middle
    Картинка поста Работа с DI-контейнером на Framework Foton

    Если кратко DI-контейнер создвет зависимости между классами через рефлексию.

    Есть два способа:

    1 Собираем или "компилируем" все зависимости в отдельные классы и работаем через них.

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

    Поэтому я выберу первый вариант для демонстрации работы и покажу на примере DI-контейнера на Framework Foton — там это система внедрения зависимостей с автоматическим разрешением аргументов конструктора через рефлексию. То есть он собирает не прям все методы и проверяет их зависимости а только конструкторы если у них они есть. Контейнер сканирует модули в каталоге dev/modules, анализирует их конструкторы, строит дерево зависимостей и генерирует готовые фасадные классы с уже разрешёнными зависимостями.

    Для понимания работы этой системы выполните следующие действия по шагам:

    Создание модуля

    Модули размещаются в dev/modules/. Каждый модуль — класс в неймспейсе Modules.

    <?php

    // dev/modules/TestDI.php

    namespace Modules;

    class TestDI

    {

    public $fileLoad;

    public function __construct(FileLoad $object)

    {

    $this->fileLoad = $object;

    }

    public function test($text)

    {

    return 'Class Load:' . get_class($this->fileLoad) . ' Text: ' . $text;

    }

    }

    Если конструктор принимает объект с type-hint, контейнер автоматически найдёт этот класс и рекурсивно разрешит его собственные зависимости.

    Конфигурация релизов

    Файл dev/facade.php содержит класс Dev\Facade. Каждый метод — это «релиз»: именованная конфигурация сборки модуля.

    <?php

    namespace Dev;

    class Facade

    {

    private $core;

    public function __construct()

    {

    $this->core = new \Foton\Core();

    }

    public function realise20($arg = [])

    {

    return [

    'Test' => ['class' => 'Modules\TestDI', 'arg' => []],

    ];

    }

    public function realise12($arg = [])

    {

    return [

    'Test' => ['class' => 'Modules\TestDI', 'arg' => []],

    ];

    }

    }

    Структура возвращаемого массива:

    'ИмяФасада' => [

    'class' => 'ModulesИмяКласса', // класс модуля

    'arg' => ['paramName' => value], // переопределение аргументов конструктора

    ]

    Ключ 'Test' — имя, по которому модуль будет доступен через $this->core->obj('Test')

    'class' — полное имя класса модуля

    'arg' — ассоциативный массив переопределяемых аргументов конструктора (имя параметра → значение). Если аргумент не указан и не является объектом, генерируется предупреждение

    Запуск генерации Из командной строки введите

    Базовая генерация фасадов

    php foton di autoload

    Генерация + вывод всех найденных модулей с зависимостями

    php foton di autoload load

    Генерация + вывод ошибок

    php foton di autoload error

    Генерация + вывод всех созданных фасадов

    php foton di autoload facade

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

    После генерации модуль доступен через ядро:

    $result = $this->core->obj('Test')->realise20()->test('text');

    // Вывод: Class Load:\Modules\FileLoad Text: text

    Цепочка вызовов: obj('Test') возвращает сгенерированный фасад Dev\DI\Facades\Test, метод realise20() создаёт экземпляр \Modules\TestDI со всеми зависимостями и возвращает его, test('text') — метод самого модуля.

    Посмотрите что у вас получилось, готовый файл класса со всеми зависимостями попадет в dev/di/facades/test.php

    <?php

    class Test

    {

    public $propertyClass;

    public function realise20($arg = [])

    {

    // Сначала создаются зависимости (в обратном порядке)

    $this->propertyClass["Class_Foton_Core"] = new \Foton\Core();

    $this->propertyClass["Class_Modules_FileLoad"] = new \Modules\FileLoad(

    $this->propertyClass["Class_Foton_Core"]

    );

    // Аргументы можно переопределить через $arg

    if (count($arg) > 0) {

    $arg = array_replace([$this->propertyClass["Class_Modules_FileLoad"]], $arg);

    } else {

    $arg = [$this->propertyClass["Class_Modules_FileLoad"]];

    }

    // Создание целевого модуля

    $this->propertyClass["Test"] = new \Modules\TestDI(...$arg);

    return $this->propertyClass["Test"];

    }

    }

    Зависимости создаются снизу вверх: сначала классы без зависимостей, затем классы, которые их используют, и в конце — целевой модуль. Массив $arg позволяет переопределить аргументы конструктора при вызове.

    Вот здесь очень хорошо видно как это работает.

    Примеры использования

    Пример 1. Модуль с несколькими зависимостями

    <?php

    // dev/modules/Logger.php

    namespace Modules;

    class Logger

    {

    public $fileLoad;

    public function __construct(FileLoad $fileLoad)

    {

    $this->fileLoad = $fileLoad;

    }

    public function write($message)

    {

    $this->fileLoad->save('log.txt', $message);

    return "Logged: $message";

    }

    }

    <?

    // dev/modules/UserService.php

    namespace Modules;

    class UserService

    {

    public $logger;

    public $fileLoad;

    public function __construct(Logger $logger, FileLoad $fileLoad)

    {

    $this->logger = $logger;

    $this->fileLoad = $fileLoad;

    }

    public function register($name)

    {

    $this->logger->write("User registered: $name");

    return "User $name registered";

    }

    }

    Конфигурация в Facade:

    public function realise30($arg = [])

    {

    return [

    'User' => ['class' => 'Modules\UserService', 'arg' => []],

    ];

    }

    Контейнер рекурсивно разрешит цепочку: UserService → Logger → FileLoad → Foton\Core. Сгенерированный фасад:

    public function realise30($arg = [])

    {

    $this->propertyClass["Class_Foton_Core"] = new \Foton\Core();

    $this->propertyClass["Class_Modules_FileLoad"] = new \Modules\FileLoad(

    $this->propertyClass["Class_Foton_Core"]

    );

    $this->propertyClass["Class_Modules_Logger"] = new \Modules\Logger(

    $this->propertyClass["Class_Modules_FileLoad"]

    );

    if (count($arg) > 0) {

    $arg = array_replace([

    $this->propertyClass["Class_Modules_Logger"],

    $this->propertyClass["Class_Modules_FileLoad"]

    ], $arg);

    } else {

    $arg = [

    $this->propertyClass["Class_Modules_Logger"],

    $this->propertyClass["Class_Modules_FileLoad"]

    ];

    }

    $this->propertyClass["User"] = new \Modules\UserService(...$arg);

    return $this->propertyClass["User"];

    }

    Вызов:

    $result = $this->core->obj('User')->realise30()->register('Иван');

    Пример 2. Переопределение аргументов конструктора

    Модуль со скалярным аргументом:

    <?php

    // dev/modules/Cache.php

    namespace Modules;

    class Cache

    {

    public $fileLoad;

    public $ttl;

    public function __construct(FileLoad $fileLoad, $ttl = 3600)

    {

    $this->fileLoad = $fileLoad;

    $this->ttl = $ttl;

    }

    public function get($key)

    {

    return "Cache[$key] ttl={$this->ttl}";

    }

    }

    Конфигурация с переопределением ttl:

    public function realise40($arg = [])

    {

    return [

    'Cache' => ['class' => 'Modules\Cache', 'arg' => ['ttl' => 60]],

    ];

    }

    public function realise41($arg = [])

    {

    return [

    'Cache' => ['class' => 'Modules\Cache', 'arg' => ['ttl' => 86400]],

    ];

    }

    После генерации можно использовать разные конфигурации:

    / Короткий TTL

    $short = $this->core->obj('Cache')->realise40()->get('user:1');

    // Вывод: Cache[user:1] ttl=60

    // Длинный TTL

    $long = $this->core->obj('Cache')->realise41()->get('user:1');

    // Вывод: Cache[user:1] ttl=86400

    Краткая инструкция:

    1. Положить модуль в dev/modules/

    2. Описать релиз в Dev\Facade

    3. Сгенерировать

    php foton di autoload

    1. Использовать

    $this->core->obj('ИмяФасада')->имяРелиза()->методМодуля(аргументы);

    Иконка глаза10

    Комментарии

    0

    Постройте личный план изучения Основы React, React Router и Redux Toolkit до уровня Middle — бесплатно!

    Основы React, React Router и Redux Toolkit — часть карты развития Frontend, Mobile

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Zustand

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.8
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Next.js - с нуля

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.7
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Feature-Sliced Design

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.6
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста Тестирование React-компонентов с Jest и React Testing Library
    Иконка аватараАнтон
    Иконка календаря07 октября 2026
    JestReact Testing LibraryТестирование+ 1middleИконка уровня middle

    Тестирование React-компонентов с Jest и React Testing Library

    Jest и React Testing Library: как настроить окружение, писать тесты на поведение пользователя, мокировать запросы и тестировать кастомные хуки.

    Иконка чипа0
    Иконка глаза29
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря07 октября 2026
    Claude CodeAI-инструментыDevOps+ 2middleИконка уровня middle

    Roo Code в VS Code: подключение Claude из России

    Roo Code начинает работать из России после одной правки в настройках: провайдер — Anthropic, в поле ключа — ваш API-ключ, в поле адреса — прокси, который отвечает без VPN и берёт оплату рублями. Само расширение ставится из Marketplace обычным порядком и остаётся нетронутым: ни форка, ни патча, ни туннеля. Ключ и адрес выдаёт [AI для кода](https://purpleschool.ru/ai-for-code). Ниже — установка, настройка провайдера, режимы Roo Code и ошибки, на которых спотыкается первое подключение.

    Иконка чипа0
    Иконка глаза44
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря06 октября 2026
    Claude CodeAI-инструментыDevOps+ 2middleИконка уровня middle

    Claude Code или Cursor: что выбрать в 2026 году

    Короткий ответ: Claude Code берут, когда агент должен работать сам — в терминале, по инструкциям из репозитория, без открытого редактора; Cursor — когда нужен редактор, в котором ассистент всегда под

    Иконка чипа0
    Иконка глаза124
    Иконка комментариев0
    Иконка чипа0