Laravel: сервіс-контейнер, провайдери, фасади
20 питань · ~20 хв · Версія v3.0
Увійдіть, щоб продовжити
Як контейнер розв'язує залежності, прив'язки й атрибути Laravel 13, контекстні прив'язки й теги, сервіс-провайдери й фасади - питання всіх рівнів, від junior до lead.
- За спробу
- 20
- У пулі
- 49
- Проходжень
- 0
- Середній бал
- -
- Пройшли на 70%+
- -
Питання для підготовки
19 питань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, події - усе резолвиться через контейнер.
Шлях запиту:
public/index.php- єдина точка входу; підключає автозавантажувач Composer.- Створюється екземпляр застосунку (Service Container) із
bootstrap/app.php. - HTTP Kernel обробляє запит, завантажує Service Providers (
register→boot). - Запит проходить глобальні middleware (наприклад, обробка сесій, CSRF).
- Router зіставляє URL із маршрутом, виконуються middleware маршруту.
- Викликається контролер/замикання, формується Response.
- Відповідь проходить middleware у зворотному порядку й повертається клієнту; виконується
terminate().
Ключова ідея: контейнер і провайдери бутстрапять застосунок, а middleware утворюють «цибулю» навколо обробки запиту.
Service Providers - центральне місце бутстрапу застосунку. Саме тут реєструються біндинги контейнера, слухачі подій, middleware, маршрути та публікація конфігів.
class AppServiceProvider extends ServiceProvider
{
// лише біндинги в контейнер
public function register(): void
{
$this->app->singleton(Parser::class);
}
// виконується після реєстрації всіх провайдерів
public function boot(): void
{
Gate::define('admin', fn ($u) => $u->is_admin);
}
}
Правило: у register() - лише біндинги (інші сервіси можуть бути ще не зареєстровані); у boot() - усе інше.
Dependency Injection - патерн, за якого клас отримує залежності ззовні (зазвичай через конструктор), а не створює їх сам. Це знижує зв'язування й полегшує тестування (можна підсунути мок).
class OrderController
{
public function __construct(
private PaymentGateway $gateway, // інжектується контейнером
) {}
}
У Laravel DI працює «з коробки»: контейнер читає type-hints і автоматично будує граф залежностей. Інжектити можна й у методи контролера (method injection), зокрема сам Request.
Фасади надають зручний статичний інтерфейс до об'єктів із Service Container.
Cache::put('key', 'value', 60);
Route::get('/', fn () => view('home'));
Попри статичний синтаксис, це не справжні статичні методи: фасад через __callStatic() дістає реальний об'єкт із контейнера й викликає метод уже на ньому. Тому фасади тестовані - їх можна мокати:
Cache::shouldReceive('get')->once()->andReturn('value');
Кожен фасад має «accessor» - рядковий ключ сервісу в контейнері.
Прочитати - ще не значить знати
20 питань, по одному на екран, ~20 хв. Після завершення - розбір кожної помилки з посиланням на питання.