Урок 01

Как 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;
    }
}

Каждая команда — класс.

Поток запроса

Упрощённо:

  1. public/index.php — точка входа.
  2. Application — загрузка.
  3. Kernel — HTTP-ядро.
  4. Router — определение маршрута.
  5. Middleware — до контроллера.
  6. Controller — обработка.
  7. Service / Repository — логика.
  8. Eloquent — данные.
  9. Response — ответ.
  10. Middleware (after) — после.
  11. 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: глубокое погружение.