Основы и архитектура
Жизненный цикл запроса, сервис-контейнер, провайдеры, фасады, Artisan.
Junior Что такое Laravel и какие его ключевые особенности?
Laravel — PHP-фреймворк с открытым исходным кодом, построенный по паттерну MVC.
Ключевые особенности:
- Eloquent ORM — реализация ActiveRecord для работы с БД;
- Blade — встроенный шаблонизатор;
- Сервис-контейнер — DI-контейнер для управления зависимостями;
- Artisan — CLI-инструмент (миграции, генерация кода, очереди);
- богатая экосистема: очереди, события, планировщик задач, кэш, аутентификация «из коробки»;
- пакеты первой стороны: Sanctum, Horizon, Telescope, Octane и др.
Философия фреймворка — «convention over configuration»: осмысленные значения по умолчанию и выразительный синтаксис.
Junior Что умеет Artisan? Приведите примеры полезных команд и как создать свою.
Artisan — CLI Laravel (php artisan).
Полезные команды:
php artisan serve # встроенный dev-сервер
php artisan migrate / migrate:fresh --seed
php artisan make:model Post -mcr # модель + миграция + ресурсный контроллер
php artisan tinker # REPL с загруженным приложением
php artisan route:list # все маршруты
php artisan queue:work # воркер очередей
php artisan config:cache / route:cache / optimize
php artisan down / up # maintenance-режим
Своя команда:
php artisan make:command SyncReports
class SyncReports extends Command
{
protected $signature = 'reports:sync {--force}';
protected $description = 'Синхронизация отчётов';
public function handle(): int
{
$this->info('Start');
// логика
return self::SUCCESS;
}
}
Запуск: php artisan reports:sync --force. Команды также можно планировать через routes/console.php (Scheduler).
Junior Как устроена конфигурация в Laravel и что делает config:cache?
Конфигурация — PHP-файлы в config/, каждый возвращает массив. Доступ: config('app.name'), config('database.default').
Значения берутся из .env через хелпер env('APP_NAME', 'default').
Важно: env() вне конфигов использовать нельзя — после php artisan config:cache .env больше не читается, и env() вернёт null.
Деплой-оптимизация:
php artisan config:cache # сливает все конфиги в один bootstrap/cache/config.php
php artisan config:clear # сброс
Кастомный конфиг: создать config/billing.php и читать config('billing.key').
Middle Опишите жизненный цикл HTTP-запроса в Laravel.
- Точка входа —
public/index.php. Загружается автолоадер Composer, создаётся экземпляр приложения (bootstrap/app.php). - Kernel — запрос передаётся HTTP Kernel (
Illuminate\Foundation\Http\Kernel). Kernel регистрирует bootstrapper'ы: загрузка конфигурации,.env, обработка ошибок, фасады, сервис-провайдеры. - Сервис-провайдеры — выполняются методы
register()(биндинги в контейнер), затемboot()(роуты, события, view-композеры). - Роутинг — запрос проходит глобальный middleware-стек, затем Router сопоставляет URI с маршрутом.
- Middleware маршрута — выполняются middleware группы и конкретного маршрута (web: сессии, CSRF и т.д.).
- Контроллер / замыкание — выполняется логика, возвращается Response.
- Обратный путь — ответ проходит middleware в обратном порядке и отправляется клиенту. Вызывается
terminate()у terminable-middleware (уже после отправки ответа).
Middle Что такое Service Container и как он работает?
Service Container — DI-контейнер, ядро Laravel. Управляет созданием объектов и их зависимостями.
Биндинг:
$this->app->bind(PaymentGateway::class, StripeGateway::class); // интерфейс → реализация
$this->app->singleton(ReportService::class); // один экземпляр на запрос
$this->app->instance('config.custom', $object); // готовый экземпляр
Разрешение (resolve):
$service = app(ReportService::class);
$service = resolve(ReportService::class);
Контейнер умеет автовайринг: через рефлексию анализирует type-hint'ы конструктора и рекурсивно создаёт зависимости. Если тип — интерфейс, требуется явный биндинг.
Инъекция работает в конструкторах контроллеров, job'ов, listener'ов, а также в методах контроллеров (method injection).
Middle Чем `bind()`, `singleton()` и `instance()` отличаются в контейнере?
bind()— при каждом resolve создаётся новый экземпляр:$this->app->bind(Service::class, fn ($app) => new Service($app['config']));singleton()— экземпляр создаётся один раз и переиспользуется на протяжении всего жизненного цикла приложения (запроса):$this->app->singleton(Cache::class, fn () => new Cache($redis));instance()— регистрирует уже созданный объект под ключом:$this->app->instance(Service::class, new Service());
Практический ориентир: stateless-сервисы — bind; дорогие или stateful (соединение, репозиторий с состоянием) — singleton.
Middle Что такое Service Provider и зачем нужны методы register() и boot()?
Service Provider — место регистрации сервисов приложения. Все провайдеры перечислены в bootstrap/providers.php (Laravel 11+) / config/app.php (старее).
register()— только биндинги в контейнер. Нельзя рассчитывать на другие сервисы: порядок загрузки провайдеров не гарантирует их доступность.boot()— вызывается после регистрации всех провайдеров. Здесь можно использовать любые сервисы: регистрация роутов, view-композеров, слушателей событий, валидационных правил.
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(BillingService::class);
}
public function boot(): void
{
View::composer('layouts.app', NavComposer::class);
}
}
Deferred-провайдеры (с $defer = true / DeferrableProvider) загружаются лениво — только когда их сервис реально запрошен.
Senior Что такое фасады? Как они работают «под капотом» и в чём их критика?
Фасад — статический интерфейс доступа к сервису из контейнера.
Как работает: базовый класс Facade определяет __callStatic(), который берёт строку из getFacadeAccessor() (например, 'cache'), резолвит сервис из контейнера и проксирует вызов на реальный объект:
Cache::get('key');
// эквивалентно:
app('cache')->get('key');
Это не статические методы реального класса — поэтому фасады легко мокать в тестах (Cache::shouldReceive(), Event::fake()).
Критика:
- скрытые зависимости — по сигнатуре класса не видно, что он использует;
- напоминает глобальное состояние / Service Locator (антипаттерн);
- затрудняет юнит-тестирование без фреймворка.
Альтернатива — явная инъекция зависимостей через конструктор. В Laravel оба подхода равноправны; фасад — сахар над контейнером.