Пакет · di

Установка и требования

У Winter DI одна runtime-зависимость и требуется PHP 8.4. Обязательных расширений нет — Swoole опционален и влияет только на request-scope.

Системные требования

  • Версия PHP — 8.4 или выше. Атрибут #[Lazy] внедряет нативный ленивый proxy PHP 8.4 (ReflectionClass::newLazyProxy()), которого нет в более ранних версиях.
  • psr/container^2.0. Устанавливается автоматически; контейнер реализует его ContainerInterface.
  • Операционная система — переносимо. В ядре нет зависимости от POSIX или конкретной платформы.

Проверьте версию PHP командой php -v.

bash
composer require flytachi/winter-di

Опционально: Swoole

ext-swooleопционален. Он важен только для request-scope: под Swoole request-scoped экземпляр хранится в контексте корутины, поэтому каждый параллельный запрос получает свою копию. Без Swoole (PHP-FPM или CLI) request-scope ведёт себя как singleton — один процесс обслуживает один запрос, так что кэш на уровне процесса уже корректен.

bash
# Проверить, загружен ли Swoole
php -m | grep swoole

Swoole не нужен, чтобы пользоваться контейнером, автовайрингом, атрибутами или двумя другими scope’ами. Подробности — в Request-scope и Swoole.

Bootstrap

Инициализируйте контейнер один раз при старте приложения. Container::init() создаёт экземпляр и сохраняет его как процессный синглтон, чтобы к нему можно было обратиться откуда угодно через Container::getInstance().

bootstrap.php
<?php

require 'vendor/autoload.php';

use Flytachi\Winter\DI\Container;
use Flytachi\Winter\DI\Scanner;
use Flytachi\Winter\DI\Collector\DICollector;

// 1. Создаём контейнер
$container = Container::init();

// 2. Авторегистрируем аннотированные классы (#[Singleton], #[Request], #[Transient])
Scanner::run(__DIR__ . '/src', cache: __DIR__ . '/var/cache/di.php')
  ->collect(new DICollector($container))
  ->execute();

// 3. Регистрируем привязки интерфейсов и фабрики
$container->register(AppServiceProvider::class);

Три шага независимы — можно пропустить шаг со Scanner и зарегистрировать всё вручную, либо пропустить провайдеры, если вы полагаетесь только на атрибуты и автовайринг.

Что даёт каждый шаг

Шаг 2 (Scanner + DICollector) находит классы с scope-атрибутом и привязывает их — см. Сканирование и автообнаружение. Шаг 3 (ServiceProvider) — место для привязок интерфейс → реализация и фабрик-замыканий — см. Сервис-провайдеры.

Следующие шаги