Laravel: разработка веб‑приложений на PHP с нуля до продакшена

Курс знакомит с основами Laravel и ключевыми компонентами фреймворка: маршрутизацией, контроллерами, Blade, базой данных через Eloquent и безопасностью. В процессе вы соберёте полноценное приложение, научитесь тестировать, оптимизировать и разворачивать проект.

1. Введение в Laravel и подготовка окружения

Введение в Laravel и подготовка окружения

Что такое Laravel

Laravel — это PHP-фреймворк для разработки веб‑приложений. Он даёт готовый набор решений для типичных задач: маршрутизация (какой URL что делает), работа с базой данных, шаблоны страниц, безопасность, очереди, отправка почты, тестирование и деплой.

Laravel особенно ценят за:

  • Быстрый старт: можно поднять рабочее приложение за считанные минуты
  • Понятную структуру проекта: где что лежит и за что отвечает
  • Экосистему: официальные инструменты для локальной разработки, очередей, фоновых задач, аутентификации
  • Сообщество и документацию: много готовых решений и материалов
  • Официальный сайт и документация:

  • Laravel
  • Документация Laravel
  • Что мы будем считать готовым окружением

    К концу статьи у вас должно быть окружение, в котором вы можете:

  • создать новый проект Laravel
  • запустить локальный сервер разработки
  • открыть приложение в браузере
  • понимать, где настраиваются переменные окружения и подключение к базе данных
  • Базовые понятия, которые понадобятся

    Фреймворк

    Фреймворк — это набор правил и библиотек, которые помогают строить приложение одинаковым, предсказуемым способом. Это экономит время и снижает количество ошибок.

    MVC (очень коротко)

    Laravel часто описывают через MVC:

  • Model (модель) — работа с данными и бизнес‑логикой (часто — таблицы в базе данных)
  • View (представление) — то, что видит пользователь (HTML‑страницы)
  • Controller (контроллер) — принимает запрос, вызывает нужную логику и возвращает ответ
  • Важно: в Laravel не всё строго укладывается в MVC, но как ориентир это полезно.

    Composer

    Composer — менеджер зависимостей для PHP. Он скачивает и обновляет библиотеки (в том числе сам Laravel) и фиксирует версии в файле composer.json.

  • Composer
  • Artisan

    Artisan — консольная утилита Laravel. Ею создают файлы проекта, запускают миграции, чистят кэши, запускают локальный сервер и многое другое.

    Команды выглядят так: php artisan ....

    Как устроен проект Laravel (первые ориентиры)

    Ниже — самая важная навигация по папкам. Полное понимание придёт позже, но уже сейчас нужно знать, где искать маршруты, контроллеры и настройки.

    | Путь | Для чего нужен | | --- | --- | | routes/web.php | Маршруты для веб‑страниц (обычно с сессиями и CSRF‑защитой) | | app/Http/Controllers | Контроллеры, которые обрабатывают запросы | | resources/views | Шаблоны страниц (Blade) | | app/Models | Модели (часто соответствуют таблицам БД) | | database/migrations | Миграции — описание структуры таблиц через код | | config | Конфигурационные файлы | | public | Точка входа для веб‑сервера и публичные ассеты | | storage | Логи, кэши, файлы, которые пишет приложение | | .env | Переменные окружения (подключение к БД, ключи и т.д.) |

    Что происходит при открытии страницы

    Когда вы открываете URL в браузере, Laravel проходит понятный маршрут: запрос приходит в приложение, выбирается подходящий маршрут, выполняется код, возвращается ответ.

    !Упрощённая схема прохождения запроса через Laravel

    Выбор способа установки

    Есть несколько рабочих вариантов. Выберите тот, который соответствует вашей ОС и опыту.

    Вариант A: локальная установка PHP и Composer

    Подходит, если вы хотите понимать окружение глубже и не боитесь установить зависимости вручную.

    Понадобится:

  • PHP (актуальные версии Laravel обычно требуют современный PHP; сверяйтесь с документацией)
  • Composer
  • база данных (часто MySQL или PostgreSQL)
  • Node.js (нужен для сборки фронтенда через Vite)
  • Официальные источники:

  • PHP
  • Node.js
  • Требования и установка Laravel
  • Если нужен простой комплект «всё в одном» для локальной разработки, можно рассмотреть:

  • XAMPP
  • Вариант B: Laravel Sail (Docker)

    Laravel Sail — официальный способ работать с Laravel через Docker. Вы получаете изолированное окружение (PHP, база, Redis и т.д.) без ручной установки сервисов.

  • Laravel Sail
  • Подходит, если:

  • вы хотите одинаковое окружение на любом компьютере
  • вы планируете работать в команде
  • вам удобно использовать Docker
  • Вариант C: Laravel Herd (особенно удобно на macOS и Windows)

    Laravel Herd — официальный инструмент, который упрощает локальную разработку на Laravel: ставит нужные версии PHP и помогает запускать проекты.

  • Laravel Herd
  • Вариант D: Laravel Valet (macOS)

    Valet — лёгкое окружение для macOS, удобно для разработки множества проектов.

  • Laravel Valet
  • Практика: создаём и запускаем первый проект

    Ниже показан универсальный путь через Composer. Он работает, если у вас уже установлены PHP и Composer.

    Создание проекта

    В терминале выполните:

    Что произошло:

  • Composer скачал Laravel и зависимости
  • создал структуру папок проекта
  • Запуск локального сервера

    Запустите:

    После этого откройте адрес, который покажет терминал (часто это http://127.0.0.1:8000).

    Проверка, что всё работает

    Если вы видите стартовую страницу Laravel, значит:

  • PHP работает
  • зависимости установлены
  • приложение запускается
  • Дополнительно можно проверить версии:

    Настройка .env и подключение базы данных (минимум на старте)

    Файл .env хранит переменные окружения — настройки, которые отличаются между компьютерами и окружениями (локально, тест, продакшен). Обычно в репозиторий его не коммитят.

    Самая частая настройка на старте — база данных. В .env есть блок DB_.... Пример (значения зависят от вашей БД):

    Общий принцип:

  • DB_CONNECTION — тип базы (например, mysql)
  • DB_HOST и DB_PORT — адрес и порт сервера БД
  • DB_DATABASE — имя базы
  • DB_USERNAME и DB_PASSWORD — доступ
  • В следующих статьях мы настроим миграции и начнём работать с данными.

    Git и редактор кода (рекомендуется сразу)

    Для курса удобно вести проект в Git, чтобы фиксировать изменения и легко откатываться.

  • Git
  • Минимальный старт:

    Частые проблемы при запуске и как их распознать

  • Порт занят: если php artisan serve ругается, попробуйте другой порт: php artisan serve --port=8080
  • Нет прав на запись: Laravel должен уметь писать в storage и bootstrap/cache
  • Не хватает расширений PHP: ошибки при composer install часто указывают, какого расширения нет (например, openssl, mbstring)
  • Неправильный .env: если позже появятся ошибки подключения к БД, первым делом проверяйте DB_... параметры
  • Что дальше по курсу

    Дальше мы начнём писать код приложения: разберём маршруты, контроллеры и представления, а затем подключим базу данных через миграции и модели. Важно, что окружение уже готово: вы сможете повторять каждый шаг и видеть результат в браузере.

    2. Маршрутизация, контроллеры и жизненный цикл запроса

    Маршрутизация, контроллеры и жизненный цикл запроса

    После установки и запуска проекта (предыдущая статья) следующий шаг — понять, как Laravel решает, какой код выполнить при открытии конкретного URL, и где этот код должен жить. Для этого нам нужны три опорных темы:

  • Маршрутизация: сопоставление URL и HTTP-метода с обработчиком.
  • Контроллеры: организация обработчиков в виде классов.
  • Жизненный цикл запроса: путь запроса через фреймворк до ответа.
  • Официальные разделы документации, которые соответствуют теме:

  • Маршрутизация Laravel
  • Контроллеры Laravel
  • Middleware Laravel
  • Жизненный цикл запроса
  • Что такое маршрут и зачем он нужен

    Маршрут (route) — это правило, которое говорит Laravel:

  • какой HTTP-метод (например, GET или POST) пришёл;
  • какой путь (например, /profile);
  • какой обработчик надо выполнить (замыкание или метод контроллера).
  • В браузере вы чаще всего делаете GET-запросы (открываете страницы). Но формы, API и интерактивные действия часто используют POST, PUT/PATCH, DELETE.

    Основные HTTP-методы в веб-приложениях

    | Метод | Типичное назначение | Пример | | --- | --- | --- | | GET | получить страницу или данные | открыть список товаров | | POST | создать новый ресурс | отправить форму регистрации | | PUT / PATCH | обновить существующий ресурс | изменить профиль | | DELETE | удалить ресурс | удалить комментарий |

    Где в Laravel описываются маршруты

    Маршруты находятся в папке routes.

  • routes/web.php — маршруты для веб‑страниц (обычно с сессиями и CSRF‑защитой).
  • routes/api.php — маршруты для API (обычно без сессий, часто с токенами, с префиксом /api).
  • Разница важна: веб‑маршруты по умолчанию «живут» в группе middleware web, а API‑маршруты — в группе api. Это влияет на поведение запросов (сессии, cookies, CSRF и т.д.).

    Первые маршруты: самый простой пример

    Откройте routes/web.php и добавьте:

    Теперь запустите сервер (если он не запущен):

    И откройте http://127.0.0.1:8000/hello.

    Какие ответы можно возвращать из маршрута

    Laravel умеет преобразовывать разные типы данных в HTTP‑ответ:

  • строка: return 'OK';
  • представление (шаблон): return view('welcome');
  • JSON: return ['status' => 'ok'];
  • редирект: return redirect('/');
  • Параметры маршрута

    Часто URL содержит часть, которая меняется: идентификатор, slug, имя.

    Обязательный параметр

    Если вы откроете /users/10, Laravel подставит 10 в slug = null) { return slug}" : 'Articles list'; }); php Route::get('/orders/{id}', function (string id}"; })->whereNumber('id'); php Route::get('/dashboard', function () { return 'Dashboard'; })->name('dashboard'); php url = route('admin.users'); php Route::middleware(['auth'])->group(function () { Route::get('/profile', function () { return 'My profile'; }); }); bash php artisan make:controller UserController php use Illuminate\Support\Facades\Route; use App\Http\Controllers\UserController;

    Route::get('/users/{id}', [UserController::class, 'show']); php namespace App\Http\Controllers;

    use Illuminate\Http\Request;

    class UserController extends Controller { public function show(string id}"; } }

    Если пользователь не найден, Laravel вернёт 404.

    Middleware: фильтры до и после выполнения обработчика

    Middleware — это слой, который выполняется до (и иногда после) контроллера/маршрута. Он может:

  • проверять авторизацию (auth);
  • ограничивать частоту запросов (throttling);
  • включать CSRF‑проверку для форм;
  • добавлять заголовки ответа;
  • перенаправлять пользователя.
  • Middleware можно назначать:

  • на отдельный маршрут: Route::get(...)->middleware('auth');
  • на группу маршрутов: Route::middleware([...])->group(...)
  • Важно: веб‑маршруты по умолчанию используют middleware‑группу web, где уже есть важные вещи вроде сессий и CSRF.

    Жизненный цикл запроса: что происходит от URL до ответа

    Понимание жизненного цикла помогает отлаживать ошибки и осознанно подключать middleware, контроллеры и сервисы.

    !Блок-схема прохождения запроса через ключевые компоненты Laravel

    Упрощённый путь запроса выглядит так:

  • Браузер отправляет HTTP‑запрос на ваш сервер.
  • В Laravel точка входа — public/index.php.
  • Загружается приложение (bootstrap), поднимаются настройки и контейнер.
  • Запрос попадает в HTTP Kernel, который запускает нужные middleware.
  • Роутер ищет подходящий маршрут в routes/web.php или routes/api.php.
  • Если маршрут ведёт на контроллер, вызывается метод контроллера.
  • Формируется ответ (строка, view, JSON, redirect и т.д.).
  • Ответ проходит обратно через middleware (если они выполняют пост‑обработку).
  • Готовый HTTP‑ответ отправляется клиенту.
  • Практический вывод:

  • 404 часто означает, что маршрут не найден (или не совпал метод/путь).
  • 403/redirect на login часто означает, что middleware не пропускает запрос.
  • Проблемы с формами в веб‑маршрутах часто связаны с CSRF.
  • Полезные Artisan-команды для маршрутов

    Показать все маршруты приложения:

    Если вы меняли маршруты или конфигурацию и видите странное поведение, иногда помогают очистка кэшей:

    Типичные ошибки и как их быстро распознавать

  • 404 Not Found
  • - маршрут отсутствует или путь написан иначе; - вы открываете
    /api/..., но описали маршрут в web.php (или наоборот).
  • 405 Method Not Allowed
  • - URL есть, но вы делаете
    POST, а маршрут описан как GET.
  • 419 Page Expired
  • - чаще всего CSRF‑ошибка при отправке формы в
    web.php.
  • Unexpected behavior после правок
  • - проверьте
    php artisan route:list и выполните php artisan optimize:clear.

    Итог

    Теперь у вас есть базовая картина:

  • где находятся маршруты Laravel и чем отличаются web.php и api.php`;
  • как писать маршруты с параметрами, именами и группами;
  • как переносить логику в контроллеры;
  • что такое middleware и на каком этапе они влияют на запрос;
  • как запрос проходит через Laravel от входа до ответа.
  • В следующих материалах мы начнём связывать это с представлениями (Blade) и данными (модели и база), чтобы маршруты и контроллеры не просто возвращали строки, а строили полноценные страницы и операции CRUD.

    3. Blade, вёрстка интерфейса и формы

    Blade, вёрстка интерфейса и формы

    В прошлой статье мы научились связывать URL с кодом через маршруты и контроллеры. Но возвращать строки из обработчиков удобно только для первых экспериментов. Дальше нам нужно собирать полноценные страницы: общий каркас сайта, повторяющиеся блоки, вывод данных, формы, сообщения об ошибках.

    Для этого в Laravel используется Blade — встроенный шаблонизатор.

    Официальная документация:

  • Blade templates
  • CSRF protection
  • Validation
  • Что такое Blade и где лежат шаблоны

    Blade — это шаблонизатор Laravel, который позволяет:

  • хранить шаблоны в отдельных файлах и возвращать их из маршрутов и контроллеров
  • выводить переменные безопасно
  • писать условия и циклы прямо в шаблоне
  • собирать страницы из общего каркаса и секций
  • удобно подключать частичные шаблоны
  • Файлы шаблонов лежат в resources/views и обычно имеют расширение blade.php.

    Принцип именования при подключении:

  • файл resources/views/welcome.blade.php подключается как view('welcome')
  • файл resources/views/pages/home.blade.php подключается как view('pages.home')
  • Возвращаем view из маршрута и контроллера

    Простейший вариант из маршрута

    routes/web.php:

    Создайте файл resources/views/about.blade.php и поместите туда любой текст и Blade-вставки, которые вы изучите ниже.

    Передача данных в view

    routes/web.php:

    resources/views/hello.blade.php:

    php Имя пользователя: {{ value !!} выводит значение как есть. Используйте это только если вы уверены в источнике данных.

    Практическое правило:

  • по умолчанию используйте {{ ... }}
  • !! ... !! применяйте редко и осознанно
  • Управляющие конструкции Blade: условия и циклы

    Blade даёт директивы, которые читаются проще, чем «чистый PHP в шаблоне».

    Условие

    Пустой список

    Формы в Laravel: CSRF, старые значения и ошибки

    Формы — это место, где чаще всего возникают «странные» ошибки у новичков. В Laravel важно понимать три вещи:

  • CSRF-защита для веб-форм обязательна
  • при ошибке валидации Laravel обычно возвращает вас назад и кладёт ошибки в сессию
  • можно автоматически подставлять старые значения через old()
  • Маршруты для формы: показать и обработать

    Типичный паттерн:

  • GET /contact показывает форму
  • POST /contact обрабатывает отправку
  • routes/web.php:

    Контроллер:

    php @csrf php {{ old('email') }} php @error('email') Ошибка email: {{ message — текст ошибки для поля email.

    #### Список всех ошибок

    PUT, PATCH и DELETE из формы

    Браузерные формы чаще всего умеют только GET и POST. Для остальных методов в Laravel используется подмена метода.

    Внутри формы (вместе с @csrf) добавляют:

    И на стороне маршрутов ожидают Route::put(...).

    Подключение стилей и скриптов через Vite

    В новых версиях Laravel сборка фронтенда обычно делается через Vite. В Blade-шаблоне используется директива @vite.

    Пример:

    Это связывает ваш шаблон со сборкой ассетов.

    Типичные ошибки и быстрые проверки

  • Страница не находится
  • - проверьте php artisan route:list - убедитесь, что возвращаете view('путь.до.шаблона'), а файл реально лежит в resources/views
  • Ошибка 419 при отправке формы
  • - почти всегда забыли @csrf в форме
  • Ошибки не показываются
  • - убедитесь, что используете errors через @error или $errors->any()
  • Старые значения не подставляются
  • - используйте old('field') - убедитесь, что при ошибке происходит редирект назад

    Итог

    Теперь вы умеете собирать интерфейс на Blade:

  • возвращать шаблоны из маршрутов и контроллеров
  • выводить данные безопасно через {{ ... }}
  • использовать условия и циклы
  • строить страницы через layout и секции
  • подключать повторяющиеся части через @include
  • делать формы с CSRF, валидацией, ошибками и old()
  • В следующих шагах курса это станет базой для полноценного CRUD: список сущностей, создание, редактирование, удаление, и всё это через контроллеры, модели и базу данных.

    4. База данных: миграции, сиды и Eloquent ORM

    База данных: миграции, сиды и Eloquent ORM

    После маршрутов, контроллеров и Blade-шаблонов следующий логичный шаг — научиться хранить данные постоянно. До этого мы передавали в представления массивы-заглушки, но реальное приложение почти всегда опирается на базу данных.

    В Laravel работа с данными строится вокруг трёх опор:

  • Миграции — описывают структуру таблиц через код и позволяют воспроизводимо менять схему.
  • Сиды — заполняют базу тестовыми или стартовыми данными.
  • Eloquent ORM — удобный слой для работы с данными как с объектами (моделями), а не ручными SQL-запросами.
  • Официальная документация:

  • Database: Getting Started
  • Migrations
  • Seeding
  • Eloquent ORM
  • Как Laravel подключается к базе данных

    Подключение настраивается в .env. В первой статье мы уже видели блок DB_.... Здесь важно понять два практических правила:

  • Laravel читает значения из .env, но многие настройки кешируются, поэтому после серьёзных изменений иногда полезно выполнить php artisan optimize:clear.
  • Самый быстрый старт для обучения часто даёт SQLite: одна локальная база-файл без установки отдельного сервера.
  • Вариант для обучения: SQLite

  • Создайте файл базы:
  • В .env укажите:
  • Убедитесь, что строки DB_HOST, DB_DATABASE и другие не мешают (Laravel для SQLite обычно достаточно DB_CONNECTION=sqlite).
  • Если вы используете MySQL или PostgreSQL, остаётся стандартная настройка DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD.

    Миграции: схема базы как код

    Миграция — это PHP-файл, который описывает изменение схемы базы данных: создание таблицы, добавление столбца, изменение индексов.

    Почему это важно:

  • схема базы хранится в репозитории вместе с кодом;
  • другой разработчик или сервер может развернуть такую же схему одной командой;
  • изменения схемы идут пошагово и воспроизводимо.
  • Создаём миграцию

    Команда:

    Файл появится в database/migrations и будет содержать методы:

  • up() — применить изменение
  • down() — откатить изменение
  • Пример миграции для таблицы posts:

    Зачем нужен request) { request->validate([ 'title' => ['required', 'string', 'max:255'], 'body' => ['required', 'string'], ]);

    validated['title'], 'body' => post); }

  • Найти по id (вернёт null, если не найдено):
  • Найти или вернуть 404 автоматически:
  • Фильтрация и сортировка:
  • app/Models/User.php:

    !Диаграмма связи один-ко-многим между пользователями и постами и соответствующие методы Eloquent

    Сиды: наполнение базы данными

    Сид (seeder) — это класс, который вставляет данные в таблицы. Он полезен для:

  • тестовых данных в разработке;
  • стартовых справочников (например, роли, статусы);
  • быстрого воспроизведения проекта на новом окружении.
  • Создаём сид

    Файл: database/seeders/PostSeeder.php.

    Пример простого сида (без фабрик):

    Подключаем сид к DatabaseSeeder

    Откройте database/seeders/DatabaseSeeder.php:

    Представления Blade

    resources/views/posts/index.blade.php:

    resources/views/posts/create.blade.php:

    В этом курсе мы избегаем HTML-тегов в тексте статьи, но в вашем проекте Blade-шаблоны будут содержать HTML. Здесь важно понять механики Laravel:

  • форма отправляет POST на маршрут posts.store
  • @csrf обязателен для web.php
  • old() и post->title }}
  • @endsection

    @section('content') {{ fillable

  • Связь не работает
  • - проверьте, что в миграции есть user_id и внешний ключ - проверьте, что метод связи назван правильно и возвращает belongsTo или hasMany

    Итог

    Теперь у вас появляется полный фундамент для приложений с данными:

  • вы умеете описывать таблицы и изменения схемы через миграции
  • вы умеете наполнять базу через сиды
  • вы умеете читать и записывать данные через Eloquent, включая базовые связи
  • вы видите, как это связывается с контроллерами, маршрутами и Blade из предыдущих статей
  • Дальше логично развивать тему в сторону полноценного CRUD (редактирование и удаление), фабрик для генерации данных, пагинации, а также авторизации, чтобы user_id` брался от текущего пользователя, а не был константой.

    5. Аутентификация, авторизация и безопасность

    Аутентификация, авторизация и безопасность

    После статей про маршруты, контроллеры, Blade и базу данных у нас есть фундамент для CRUD: мы умеем принимать запросы, показывать страницы и сохранять данные. Следующий шаг, без которого почти не бывает реальных приложений, — научиться:

  • Аутентифицировать пользователя (понять кто он).
  • Авторизовать действия (понять что ему можно).
  • Настроить базовую безопасность (защита форм, данных и типовых уязвимостей).
  • Официальная документация Laravel по теме:

  • Аутентификация
  • Авторизация
  • Starter Kits
  • CSRF-защита
  • Валидация
  • Hashing
  • Encryption
  • Rate Limiting
  • Базовые определения

  • Аутентификация — процесс, который отвечает на вопрос: кто этот пользователь? Обычно через логин и пароль, OAuth или одноразовые коды.
  • Авторизация — процесс, который отвечает на вопрос: может ли этот пользователь выполнить действие? Например, редактировать пост, удалять комментарии, заходить в админку.
  • Пользователь (User) — обычно запись в таблице users, представленная моделью App\Models\User.
  • Сессия — механизм, который позволяет «помнить» пользователя между запросами. В веб-приложениях Laravel чаще всего использует сессионную аутентификацию через cookie.
  • Ключевая связка:

  • аутентификация определяет пользователя
  • авторизация проверяет право на действие
  • !Упрощённый поток входа и доступа к защищённым страницам

    Быстрый старт: Starter Kit для готовой аутентификации

    Laravel можно подключать к аутентификации «вручную», но в большинстве проектов и для обучения удобнее использовать официальный стартовый набор.

    Laravel Breeze

    Laravel Breeze — минимальный набор для регистрации, входа, выхода, сброса пароля, страниц профиля (зависит от версии). Он даёт готовые маршруты, контроллеры и представления.

    Установка (типичный поток):

    Что важно проверить после установки:

  • в routes/web.php появились маршруты аутентификации (их добавляет пакет)
  • миграции создали таблицы, связанные с пользователями (обычно users, password_reset_tokens)
  • вы можете зарегистрироваться, войти и выйти
  • Если вы используете SQLite для обучения, убедитесь, что база настроена в .env, а файл database/database.sqlite существует (как в прошлой статье).

    Аутентификация в коде приложения

    Как получить текущего пользователя

    В контроллере или любом месте, где есть контекст запроса:

    bash php artisan make:policy PostPolicy --model=Post php use App\Models\Post; use App\Models\User;

    public function update(User post): bool { return user->id; } php use App\Models\Post; use Illuminate\Http\Request;

    public function edit(Post this->authorize('update', post]); }

    public function update(Request post) { post);

    request->validate([ 'title' => ['required', 'string', 'max:255'], 'body' => ['required', 'string'], ]);

    validated);

    return redirect()->route('posts.show', post) Ссылка: редактировать @endcan

    И затем обновлять только валидированное:

    Хеширование паролей

    Пароли нельзя хранить в базе в открытом виде.

    Laravel хранит пароли в виде хеша и предоставляет фасад Hash.

  • создать хеш: Hash::make(password, this->authorize(...) и policy
  • Маршрут закрыт, но всё равно доступен
  • - забыли ->middleware('auth') или закрыли не тот маршрут
  • Посты создаются без автора
  • - проверьте, что используете this->authorize(...)
  • базовые меры безопасности: CSRF, XSS, валидация, $fillable, hashing, rate limiting
  • Следующий логичный шаг после этого материала — довести CRUD до полного (редактирование и удаление) с корректной авторизацией, а затем перейти к более продакшен-ориентированным темам: хранение файлов, очереди, тесты, логирование и деплой.

    6. API, очереди, события и фоновые задачи

    API, очереди, события и фоновые задачи

    Когда у нас уже есть базовое веб‑приложение (маршруты, контроллеры, Blade, база данных, аутентификация и авторизация), следующий шаг к продакшен‑уровню — научиться:

  • строить API, которое возвращает JSON и удобно для фронтенда, мобильных клиентов и интеграций
  • выносить тяжёлые операции в очереди (queues), чтобы не тормозить запрос пользователя
  • связывать части приложения через события (events), уменьшая связность кода
  • запускать регулярные фоновые операции через планировщик (scheduler)
  • Официальная документация Laravel по теме:

  • Routing
  • HTTP Responses
  • Eloquent API Resources
  • Validation
  • Laravel Sanctum
  • Queues
  • Events
  • Task Scheduling
  • API в Laravel

    Что такое API

    API в контексте веб‑приложения — это набор HTTP‑эндпоинтов (URL + метод), которые возвращают данные обычно в формате JSON.

    Ключевое отличие от «обычных веб‑страниц» (Blade) такое:

  • веб‑страницы возвращают HTML и часто используют сессии в браузере
  • API обычно возвращает JSON и чаще работает в stateless стиле (без ожидания состояния на стороне клиента)
  • Где описывать API‑маршруты

    По умолчанию Laravel разделяет маршруты:

  • routes/web.php — «браузерные» маршруты (сессии, CSRF, Blade)
  • routes/api.php — API‑маршруты (обычно без сессий, с префиксом /api)
  • Практический вывод:

  • если вы открываете GET /api/posts, маршрут почти всегда должен быть в routes/api.php
  • если вы отправляете HTML‑форму и получаете 419, это про web.php и CSRF
  • Базовые принципы ответов API

    Хороший API почти всегда делает следующее:

  • возвращает JSON
  • возвращает корректные HTTP‑коды статуса (например, 200, 201, 404, 422)
  • валидирует входные данные
  • Примеры ответов из контроллера:

    Ошибки валидации в Laravel для API обычно автоматически превращаются в ответ 422 Unprocessable Content с JSON‑описанием ошибок.

    !Упрощённый путь API-запроса от клиента до JSON-ответа

    Пример: простой API для постов

    Ниже мы свяжем темы из прошлых статей (маршруты, контроллеры, Eloquent, валидация) с API‑подходом.

    Маршруты API

    routes/api.php:

    Здесь {post} — это Route Model Binding: Laravel автоматически найдёт Post по id или вернёт 404.

    API‑контроллер

    Создать контроллер удобно командой:

    Пример минимальной реализации (без Blade, только JSON):

    bash php artisan make:resource PostResource php namespace App\Http\Resources;

    use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource;

    class PostResource extends JsonResource { public function toArray(Request this->id, 'title' => this->body, 'created_at' => post) { return new PostResource(token = token, ]); php use Illuminate\Support\Facades\Route;

    Route::middleware('auth:sanctum')->post('/posts', [PostController::class, 'store']);

    Повторы, таймауты и упавшие задачи

    В реальном продакшене важно понимать поведение при ошибках:

  • если задача упала, Laravel может повторить её (retry)
  • упавшие задачи можно складывать в таблицу failed_jobs
  • Создать таблицу для упавших задач:

    Посмотреть упавшие задачи:

    Перезапустить конкретную:

    !Как запрос кладёт задачу в очередь, а воркер выполняет её отдельно

    События: как уменьшать связность кода

    Зачем нужны события

    Если контроллер после создания поста должен:

  • отправить уведомление
  • записать аудит
  • отправить webhook
  • то писать всё это прямо в контроллере означает:

  • контроллер разрастается
  • логика становится трудно расширяемой
  • События решают это так:

  • «факт» случившегося оформляется как event
  • подписчики (listeners) реагируют на событие и делают свою работу
  • Event и Listener

    Создадим событие:

    Создадим слушатель:

    Пример события app/Events/PostPublished.php (идея, структура может отличаться по версии):

    Очереди и события вместе

    Слушатели тоже могут быть очередными. Тогда реакция на событие тоже уйдёт в фон.

    Для этого слушатель делает implements ShouldQueue.

    Документация: Events

    Планировщик: регулярные фоновые задачи

    Очереди запускаются «по факту» (когда вы что-то dispatch). Но часто нужны регулярные задачи:

  • чистка старых записей
  • пересчёт статистики
  • отправка ежедневных отчётов
  • синхронизация данных
  • Для этого есть Task Scheduling.

    Документация: Task Scheduling

    Где описывать расписание

    Расписание задаётся в app/Console/Kernel.php в методе schedule().

    Примеры:

    Можно запускать Job по расписанию:

    Как это работает на сервере

    На сервере обычно настраивают один cron, который каждую минуту вызывает:

    А уже Laravel решает, что именно пора запускать.

    Как связать всё в одном потоке

    Типичный продакшен‑поток может выглядеть так:

  • Клиент вызывает POST /api/posts.
  • Контроллер валидирует данные и создаёт запись posts через Eloquent.
  • Контроллер диспатчит событие PostPublished.
  • Listener реагирует на событие и ставит Job в очередь.
  • Queue worker выполняет Job (уведомление, интеграция и т.д.).
  • Scheduler раз в сутки запускает задачи обслуживания (чистки, отчёты).
  • Преимущество такой архитектуры:

  • быстрый ответ API
  • отделение ответственности (контроллер не знает деталей уведомлений)
  • устойчивость к временным сбоям внешних сервисов (через повторы задач)
  • Полезные команды для разработки и диагностики

    | Задача | Команда | | --- | --- | | Список маршрутов | php artisan route:list | | Очистить кэши | php artisan optimize:clear | | Запустить воркер | php artisan queue:work | | Проверить упавшие job | php artisan queue:failed | | Повторить упавшие job | php artisan queue:retry all | | Запустить планировщик вручную | php artisan schedule:run |

    Типичные ошибки

  • API возвращает 404
  • - маршрут добавлен в web.php, а вы обращаетесь к /api/...
  • Задачи в очереди копятся, но не выполняются
  • - не запущен php artisan queue:work - неправильно настроен QUEUE_CONNECTION
  • Ожидали фон, а job выполняется сразу
  • - вы используете драйвер sync - job не реализует ShouldQueue
  • Планировщик не запускается сам
  • - забыли настроить cron, который вызывает schedule:run каждую минуту

    Итог

    Вы добавили важные продакшен‑механики поверх базового CRUD:

  • API‑маршруты и JSON‑ответы вместо Blade
  • ресурсы API (Resources) для стабильного формата ответов
  • токен‑аутентификацию для API через Sanctum
  • очереди и воркеры для асинхронной обработки
  • события и слушателей для уменьшения связности
  • планировщик для регулярных фоновых операций
  • Дальше (за рамками этой статьи) обычно идут темы наблюдаемости и продакшена: логирование, метрики, тесты, деплой, а также более глубокая работа с очередями (например, Redis и мониторинг).

    7. Тестирование, оптимизация и деплой в продакшен

    Тестирование, оптимизация и деплой в продакшен

    К этому месту курса у вас уже есть полноценное Laravel‑приложение: маршруты и контроллеры, Blade, база и Eloquent, аутентификация и авторизация, API, очереди, события и планировщик. Осталось пройти последний мост до продакшена: доказать, что приложение работает (тестирование), сделать его быстрым и стабильным (оптимизация) и научиться безопасно выкатывать изменения (деплой).

    Полезные разделы документации:

  • Тестирование
  • HTTP Tests
  • Database Testing
  • Mocking
  • Deployment
  • Queues
  • Task Scheduling
  • Logging
  • !Схема показывает последовательность шагов от кода до продакшена

    Тестирование в Laravel

    Зачем тесты, если приложение уже работает в браузере

    Ручная проверка через браузер помогает на старте, но плохо защищает от регрессий.

    Тесты дают три практических эффекта:

  • уверенность при рефакторинге контроллеров, моделей, policy и API
  • быстрое обнаружение ошибок после изменений
  • документацию поведения: тест описывает, что система должна делать
  • Какие тесты бывают в Laravel

    В контексте Laravel чаще всего говорят о двух уровнях:

  • Unit‑тесты: проверяют небольшой кусок логики изолированно (например, метод сервиса или правило)
  • Feature‑тесты: проверяют поведение через HTTP‑уровень (маршрут → middleware → контроллер → база → ответ)
  • Практическое правило курса:

  • если вы проверяете правила доступа (policies), валидацию, ответы JSON и страницы, начните с Feature‑тестов
  • unit‑тесты добавляйте для плотной бизнес‑логики, которую удобно вызывать напрямую
  • Как запускать тесты

    Основная команда:

    Laravel использует PHPUnit (или Pest, если вы выбрали его отдельно). В этом курсе мы держимся общих принципов и примеров на стандартном тестовом раннере.

    Подготовка тестового окружения

    У Laravel обычно есть отдельные настройки для тестов.

    Ключевые идеи:

  • тесты должны работать на отдельной базе, чтобы не портить локальные данные
  • база в тестах должна быстро очищаться
  • Частый учебный вариант:

  • SQLite для тестов
  • миграции прогоняются автоматически
  • Laravel поддерживает файл .env.testing, который используется при запуске тестов.

    Создание теста

    Сгенерируем feature‑тест:

    Файл появится в tests/Feature.

    База данных в тестах: RefreshDatabase

    Типичная проблема новичков: один тест создал записи, другой неожиданно их видит.

    Для изоляции используют трейт RefreshDatabase, который приводит базу в ожидаемое состояние между тестами.

    Здесь важно понять смысл каждой части:

  • Post::factory() создаёт тестовые записи (обычно через фабрики)
  • getJson(...) делает HTTP‑запрос к API‑маршруту из routes/api.php
  • assertOk() проверяет HTTP‑код 200
  • assertJsonStructure(...) проверяет ожидаемую форму ответа (актуально при пагинации)
  • Документация по DB‑тестам: Database Testing

    Аутентификация в тестах

    Если ваш API или веб‑страницы закрыты middleware auth или auth:sanctum, тест должен действовать как вошедший пользователь.

    Пример для веб‑охраняемого маршрута:

    Ключевая идея: actingAs(this->authorize('update', author = User::factory()->create(); post = Post::factory()->create([ 'user_id' => response = intruder)->put( "/posts/{response->assertForbidden(); } bash php artisan config:cache php artisan route:cache php artisan view:cache bash php artisan optimize:clear php posts = Cache::remember('posts.latest', 60, function () { return \App\Models\Post::query() ->orderByDesc('id') ->take(10) ->get(); }); bash composer install --no-dev --optimize-autoloader bash npm ci npm run build bash php artisan migrate --force bash php artisan storage:link bash php artisan config:cache php artisan route:cache php artisan view:cache bash php artisan queue:restart bash php artisan schedule:run bash php artisan down bash php artisan up `

    Это особенно полезно, если вы делаете изменения схемы, которые могут временно ломать часть запросов.

    Наблюдаемость: логи и диагностика

    Если в продакшене «что-то пошло не так», вы должны быстро понять что именно.

    Базовый минимум:

  • настроить сбор логов
  • проверять storage/logs (или централизованный лог‑сервис)
  • Документация: Logging

    Частые проблемы при деплое и быстрые проверки

  • 500 ошибка после деплоя
  • - проверьте логи в storage/logs - проверьте права на storage и bootstrap/cache - выполните php artisan optimize:clear и затем заново config:cache
  • Изменения в .env не применились
  • - вероятно, включён кэш конфигов, выполните php artisan config:cache
  • Задачи очереди копятся и не выполняются
  • - воркер не запущен или не перезапущен после релиза - выполните
    php artisan queue:restart и проверьте менеджер процессов
  • Планировщик не работает
  • - не настроен cron, который запускает
    schedule:run раз в минуту

    Итог

    Теперь у вас есть полный путь от разработки до продакшена:

  • вы пишете feature‑тесты, которые проверяют маршруты, авторизацию, валидацию и JSON‑ответы
  • вы понимаете, какие оптимизации важны в Laravel: eager loading, пагинация, кэширование, очереди
  • вы знаете базовый сценарий деплоя: зависимости, миграции, кэши, перезапуск воркеров и scheduler
  • Это завершает «сквозную» линию курса: от первого php artisan serve` до стабильного приложения, которое можно поддерживать и развивать.