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

Middle: питання на співбесіді з теми «Service Providers»

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

2 питання

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() - усе інше.

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

Провайдери завантажуються у дві фази, і плутанина між ними дає помилки, які важко пояснити.

register() - тільки привʼязки до контейнера. На цей момент інші провайдери ще не зареєстровані, тож звертатися до чужих сервісів не можна:

public function register(): void
{
    $this->app->singleton(WeatherClient::class, function ($app) {
        return new WeatherClient(config('services.weather.key'));
    });
}

Замикання виконається пізніше - у момент першого резолву, коли все вже піднято.

boot() - усе інше. Викликається після того, як усі провайдери відпрацювали register(), тож тут доступні будь-які сервіси:

public function boot(): void
{
    Model::preventLazyLoading(! app()->isProduction());

    View::composer('layouts.app', SidebarComposer::class);

    Gate::define('publish', fn (User $user) => $user->is_editor);
}

Типова помилка - зробити в register() щось на кшталт:

public function register(): void
{
    // Провайдер конфігурації міг ще не відпрацювати.
    $key = config('services.weather.key');
    $this->app->singleton(WeatherClient::class, fn () => new WeatherClient($key));
}

Значення читається негайно, і якщо потрібний провайдер ще не завантажився, отримаєте null без жодної помилки. Всередині замикання те саме читання безпечне.

Правило: register() - сказати контейнеру, як створювати; boot() - зробити щось із уже готовим застосунком.

Докладніше в документації: Сервіс-провайдери