Как Laravel использует ООП
Зачем этот урок
Laravel — не просто фреймворк, а пример грамотной архитектуры на ООП. Понимание того, как Laravel устроен, помогает:
- Писать идиоматичный код — как задумано.
- Понимать ошибки — откуда они берутся.
- Расширять без костылей.
- Готовиться к собеседованиям.
Общая структура
Laravel построен на:
- Service Container — DI.
- Service Providers — регистрация.
- Facades — статические обёртки.
- Contracts — интерфейсы.
- Middleware — Chain of Responsibility.
- Events — Observer.
- Eloquent — Active Record.
- Artisan — CLI на Symfony Console.
Точка входа
public/index.php:
<?php
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
require __DIR__.'/../vendor/autoload.php';
(require_once __DIR__.'/../bootstrap/app.php')
->handleRequest(Request::capture());
Что здесь:
- Autoload — подключение классов.
bootstrap/app.php— создание приложения.handleRequest— обработка и ответ.
Application
Illuminate\Foundation\Application — центральный объект.
$app = new Application($basePath);
Что делает:
- Service Container — наследуется.
- Регистрация сервисов.
- Boot провайдеров.
- Environment detection.
Service Container в Laravel
Illuminate\Container\Container.
$app->bind(UserRepository::class, EloquentUserRepository::class);
$app->singleton(Cache::class, RedisCache::class);
Авторазрешение через Reflection.
Service Providers
Регистрация сервисов:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->bind(
\App\Contracts\PaymentGateway::class,
\App\Services\StripeGateway::class,
);
}
public function boot(): void
{
// после регистрации всех сервисов
}
}
register() — привязки.
boot() — после всех регистраций.
Facades
Статический доступ:
use Illuminate\Support\Facades\Cache;
Cache::put('key', 'value', 3600);
Cache::get('key');
Что под капотом: Cache::put() → app('cache')->put().
Facade — прокси к сервису из контейнера.
Contracts
Интерфейсы:
use Illuminate\Contracts\Cache\Repository;
class MyService
{
public function __construct(
private Repository $cache,
) {}
}
Laravel использует контракты везде.
Middleware
Chain of Responsibility:
class Authenticate
{
public function handle(Request $request, Closure $next): Response
{
if (!auth()->check()) {
return redirect('/login');
}
return $next($request);
}
}
Цепочка — каждый может прервать или продолжить.
Events и Listeners
Observer:
class UserRegistered
{
public function __construct(public User $user) {}
}
class SendWelcomeEmail
{
public function handle(UserRegistered $event): void
{
Mail::to($event->user)->send(new Welcome());
}
}
// dispatch
UserRegistered::dispatch($user);
Развязка — модель не знает об email.
Eloquent
Active Record:
$user = User::find(1);
$user->name = 'Иван';
$user->save();
Модель = строка БД + методы.
Отличие от Data Mapper (Doctrine) — модель знает о БД.
Jobs и Queues
Command:
class ProcessPodcast implements ShouldQueue
{
public function __construct(public Podcast $podcast) {}
public function handle(): void
{
// обработка
}
}
ProcessPodcast::dispatch($podcast);
Job — задача в очереди.
Artisan
Symfony Console:
class SendEmails extends Command
{
protected $signature = 'emails:send {user}';
public function handle(): int
{
// ...
return self::SUCCESS;
}
}
Каждая команда — класс.
Поток запроса
Упрощённо:
public/index.php— точка входа.- Application — загрузка.
- Kernel — HTTP-ядро.
- Router — определение маршрута.
- Middleware — до контроллера.
- Controller — обработка.
- Service / Repository — логика.
- Eloquent — данные.
- Response — ответ.
- Middleware (after) — после.
- Kernel::terminate — финализация.
Практика: понять контейнер
php artisan tinker
// Получить контейнер
$app = app();
// Разрешить сервис
$cache = $app->make('cache');
// Проверить привязку
$app->bound('cache'); // true
// Посмотреть привязки
$app->getBindings();
Играйся — это лучший способ понять Laravel.
Практика: свой сервис
Создай:
namespace App\Services;
class Calculator
{
public function sum(int ...$nums): int
{
return array_sum($nums);
}
}
Использование:
class HomeController
{
public function index(Calculator $calc): string
{
return '2 + 3 = ' . $calc->sum(2, 3);
}
}
Laravel сам создаст Calculator.
Итог
- Laravel — пример ООП-архитектуры.
- Container — DI.
- Providers — регистрация.
- Facades — статические прокси.
- Contracts — интерфейсы.
- Middleware — Chain.
- Events — Observer.
- Eloquent — Active Record.
- Artisan — Console.
Дальше — Service Container: глубокое погружение.