Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке PSR-11 і як він зробив контейнери залежностей взаємозамінними?

PSR-11 - мінімальний спільний інтерфейс контейнера залежностей. Усього два методи:

namespace Psr\Container;

interface ContainerInterface
{
    public function get(string $id);   // отримати запис або кинути NotFoundExceptionInterface
    public function has(string $id): bool;
}

Навіщо такий мінімалізм: стандарт описує лише отримання сервісів, а не їхню реєстрацію. Конфігурація (прив'язки, автовпровадження, синглтони) у кожного контейнера своя, а споживання - однакове.

Що це дало екосистемі:

  • Фреймворко-незалежні бібліотеки й фреймворки. Slim, Mezzio, роутери й диспетчери middleware приймають будь-який PSR-11-контейнер: PHP-DI, Symfony DependencyInjection, League Container, Laravel.
  • Laravel реалізує PSR-11: Illuminate\Container\Container - це ContainerInterface, тож сторонні бібліотеки, що очікують PSR-контейнер, працюють з ним.
  • Композиція контейнерів - делегування пошуку іншому контейнеру.

Застереження - Service Locator. PSR-11 прямо не радить передавати контейнер у бізнес-класи, щоб вони самі діставали залежності:

// Погано: прихована залежність, важко тестувати
final class ReportService
{
    public function __construct(private ContainerInterface $container) {}

    public function build(): void
    {
        $mailer = $this->container->get(Mailer::class);
    }
}

// Добре: залежність явна
final class ReportService
{
    public function __construct(private Mailer $mailer) {}
}

Контейнер - для «склеювання» застосунку на верхньому рівні (фабрики, фреймворк), а не для використання всередині логіки. Виняток - фабрики, що за природою створюють різні об'єкти за ідентифікатором.

Докладніше в документації: PSR-11: Container interface

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання