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

У чому різниця між register і boot у провайдері?

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

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() - зробити щось із уже готовим застосунком.

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

2

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