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

Питання на співбесіді: Service Container

Найпопулярніші питання з реальних Laravel/PHP співбесід для всіх рівнів

3 питання

Service Container (IoC-контейнер) керує залежностями класів і виконує dependency injection. Він уміє автоматично будувати об'єкти, рекурсивно резолвлячи їхні залежності через type-hints конструктора.

// біндинг інтерфейсу до реалізації (зазвичай у Service Provider)
$this->app->bind(PaymentGateway::class, StripeGateway::class);

// тепер усюди, де просять PaymentGateway, прийде StripeGateway
public function __construct(private PaymentGateway $gateway) {}
  • bind() - нова реалізація щоразу.
  • singleton() - один екземпляр на весь життєвий цикл запиту.
  • app(PaymentGateway::class) - ручне резолвлення.

Це серце Laravel: контролери, middleware, події - усе резолвиться через контейнер.

Докладніше в документації: Service Container

Dependency Injection - патерн, за якого клас отримує залежності ззовні (зазвичай через конструктор), а не створює їх сам. Це знижує зв'язування й полегшує тестування (можна підсунути мок).

class OrderController
{
    public function __construct(
        private PaymentGateway $gateway, // інжектується контейнером
    ) {}
}

У Laravel DI працює «з коробки»: контейнер читає type-hints і автоматично будує граф залежностей. Інжектити можна й у методи контролера (method injection), зокрема сам Request.

Докладніше в документації: Dependency Injection

Contextual binding дозволяє віддавати різні реалізації одного інтерфейсу залежно від класу, що його запитує.

$this->app->when(PhotoController::class)
    ->needs(Filesystem::class)
    ->give(fn () => Storage::disk('local'));

$this->app->when(VideoController::class)
    ->needs(Filesystem::class)
    ->give(fn () => Storage::disk('s3'));

Тобто PhotoController отримає локальний диск, VideoController - S3, хоча обидва просять Filesystem.

Споріднені можливості:

  • giveTagged() - впорснути всі сервіси з певним тегом.
  • Прив'язка примітивів: ->needs('$apiKey')->give(config('services.x.key')).

Корисно, коли одна абстракція має кілька конфігурацій у різних частинах застосунку.

Докладніше в документації: Contextual Binding