Laravel: что это, зачем и когда используется

Laravel: что это, зачем и когда используется Полезное

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

Ниже — как Laravel устроен, как поставить его и собрать маленький API, какие ошибки встречаются первыми и в каких проектах фреймворк уместен, а в каких нет. Примеры проверены на Laravel 13.33 и PHP 8.4 (24.09.2026).

Фреймворк, пакет, CMS: в чем разница

Эти слова часто смешивают, поэтому коротко:

  • Фреймворк (Laravel, Symfony) — каркас приложения. Он сам принимает запрос и вызывает ваш код в нужный момент; вы пишете контроллеры, модели, правила.
  • Пакет Composer — отдельная библиотека, которую вызываете вы (например, для работы с датами). Сам Laravel устанавливается как набор таких пакетов и опирается на десятки сторонних (например, компоненты Symfony).
  • CMS (WordPress, Bitrix) — готовый сайт с админкой: его настраивают и расширяют плагинами, а не пишут с нуля.

Laravel — не CMS: админки и готовых страниц в нем нет. Это инструмент, чтобы писать свое приложение быстрее, чем на чистом PHP.

Зачем нужен Laravel: что он берет на себя

Задача На чистом PHP В Laravel
Разобрать URL и вызвать нужный код свой роутер или цепочка if Route::get('/notes', ...)
Запрос к БД без SQL-инъекций PDO и подготовленные выражения вручную Eloquent ORM и Query Builder, параметры экранируются
Изменения схемы БД SQL-скрипты, которые надо не забыть применить миграции + php artisan migrate
Проверка входных данных десятки if и сбор ошибок $request->validate([...]), ответ 422
Защита форм от CSRF генерировать и сверять токен самому включена для routes/web.php по умолчанию
Шаблоны HTML echo с ручным экранированием Blade: {{ $x }} экранирует вывод
Фоновые задачи, почта, кеш отдельные библиотеки очереди, Mail, Cache с единым API
Генерация заготовок копирование файлов Artisan: php artisan make:model

Главный выигрыш — не в «меньше кода вообще», а в том, что типовые вещи уже сделаны единообразно и с безопасными умолчаниями. Новый разработчик в команде открывает Laravel-проект и сразу знает, где маршруты, где модели и где миграции.

Как Laravel обрабатывает запрос

Упрощенная цепочка одного HTTP-запроса:

  1. Веб-сервер отдает запрос в public/index.php — единственную публичную точку входа.
  2. Запрос проходит middleware — слои-фильтры: сессия, проверка CSRF, аутентификация, ограничение частоты.
  3. Маршрутизатор находит маршрут по методу и URL (GET /api/notes).
  4. Вызывается контроллер — класс, где лежит логика обработки.
  5. Контроллер работает с данными через модель Eloquent (класс, связанный с таблицей).
  6. Возвращается ответ: HTML из шаблона Blade, JSON или редирект.

Эту схему часто называют MVC (модель — представление — контроллер). Это упрощение: Laravel не требует строгого MVC. В API-проекте представлений (View) может не быть вовсе, а часть логики живет в очередях, событиях и отдельных сервисных классах.

Установка Laravel

Laravel 13 требует PHP 8.3 или новее (проверено по composer.json свежего проекта) и Composer — менеджер пакетов PHP. Для примеров также нужно расширение pdo_sqlite.

composer create-project laravel/laravel notes-app
cd notes-app
php artisan --version
php artisan serve

php artisan --version выведет версию фреймворка (у меня — Laravel Framework 13.33.0), а php artisan serve запустит встроенный сервер разработки на http://127.0.0.1:8000. Альтернатива — установщик laravel new notes-app, он дополнительно предлагает стартовые наборы с React, Vue или Livewire.

С Laravel 11 новый проект по умолчанию использует SQLite (DB_CONNECTION=sqlite в файле .env), поэтому для первых шагов отдельный сервер БД не нужен. Для MySQL или PostgreSQL меняются настройки DB_* в .env.

Куда смотреть в проекте:

Путь Что там
routes/web.php маршруты для браузера: сессии, cookie, CSRF
routes/api.php маршруты API с префиксом /api (появляется после php artisan install:api)
app/Http/Controllers/ контроллеры
app/Models/ модели Eloquent
database/migrations/ миграции — история изменений схемы БД
resources/views/ шаблоны Blade
.env настройки окружения и секреты, в git не коммитится
public/ единственная папка, доступная из веба

Маршруты, контроллер и Eloquent на одном примере

Соберем API заметок: список, одна заметка и создание новой. Сначала подключим файл API-маршрутов и сгенерируем модель, миграцию и контроллер одной командой:

php artisan install:api
php artisan make:model Note -mc

install:api ставит пакет Sanctum (токены для API), создает routes/api.php и подключает его к приложению. Флаг -mc у make:model означает «плюс миграция и контроллер».

Миграция описывает таблицу. В созданном файле database/migrations/..._create_notes_table.php дополняем метод up():

Schema::create('notes', function (Blueprint $table) {
    $table->id();                          // BIGINT, автоинкремент, первичный ключ
    $table->string('title', 100);          // VARCHAR(100), обязательное
    $table->text('body')->nullable();      // текст, может быть пустым
    $table->timestamps();                  // created_at и updated_at
});

Модель app/Models/Note.php — класс, связанный с таблицей notes по соглашению об именах:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Note extends Model
{
    // поля, которые разрешено заполнять массово через create()/fill()
    protected $fillable = ['title', 'body'];
}

Контроллер app/Http/Controllers/NoteController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Note;
use Illuminate\Http\Request;

class NoteController extends Controller
{
    public function index()
    {
        // SELECT * FROM notes ORDER BY id DESC
        return Note::orderByDesc('id')->get();
    }

    public function show(Note $note)
    {
        // $note уже найден по {note} из URL, иначе Laravel вернет 404
        return $note;
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required|string|max:100',
            'body'  => 'nullable|string',
        ]);

        $note = Note::create($data);

        return response()->json($note, 201);
    }
}

Маршруты routes/api.php:

<?php

use App\Http\Controllers\NoteController;
use Illuminate\Support\Facades\Route;

Route::get('/notes', [NoteController::class, 'index']);
Route::get('/notes/{note}', [NoteController::class, 'show']);
Route::post('/notes', [NoteController::class, 'store']);

Применяем миграцию, запускаем сервер и шлем запросы из второго терминала:

php artisan migrate
php artisan serve

curl -X POST -H 'Accept: application/json' -d 'title=Learn routing' -d 'body=web.php vs api.php' http://127.0.0.1:8000/api/notes
curl http://127.0.0.1:8000/api/notes

Первый запрос создаст заметку и вернет ее с кодом 201, второй — список:

{"title":"Learn routing","body":"web.php vs api.php","updated_at":"2026-09-24T11:09:59.000000Z","created_at":"2026-09-24T11:09:59.000000Z","id":1}
[{"id":1,"title":"Learn routing","body":"web.php vs api.php","created_at":"2026-09-24T11:09:59.000000Z","updated_at":"2026-09-24T11:09:59.000000Z"}]

Что здесь сделал фреймворк за нас:

  • Маршрутизация. php artisan route:list --path=notes покажет три маршрута api/notes и api/notes/{note}: префикс /api файл api.php добавляет сам.
  • Привязка модели к маршруту. В show(Note $note) Laravel сам выполнил поиск по id из URL. Запрос GET /api/notes/42 к несуществующей записи вернет 404 без единой строки проверки в коде.
  • Eloquent. Note::orderByDesc('id')->get() превращается в SQL. Увидеть его можно в php artisan tinker: Note::where('title', 'like', '%milk%')->orderByDesc('id')->toRawSql() вернет select * from "notes" where "title" like '%milk%' order by "id" desc.
  • Валидация. Если правило не выполнено, validate() прерывает обработку и возвращает 422 со списком ошибок — контроллер дальше не выполняется.

Запрос без поля title и запрос с title длиннее 100 символов:

{"message":"The title field is required.","errors":{"title":["The title field is required."]}}
HTTP 422
{"message":"The title field must not be greater than 100 characters.","errors":{"title":["The title field must not be greater than 100 characters."]}}
HTTP 422

Для обычной формы в браузере (маршрут в web.php, без Accept: application/json) Laravel вместо JSON сделает редирект назад и положит ошибки в сессию.

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

POST-маршрут в web.php отвечает 419. Неверно: положить Route::post('/notes', ...) в routes/web.php и вызвать его через curl или из стороннего клиента. Фактический результат — HTTP 419 (страница «Page Expired»), а в JSON-режиме сообщение CSRF token mismatch. Причина: маршруты web.php проходят проверку CSRF-токена (в Laravel 13 это middleware PreventRequestForgery, который дополнительно сверяет источник запроса по Origin). Исправление: для API — маршрут в routes/api.php; для HTML-формы — директива @csrf внутри <form> в шаблоне Blade. Отключать проверку CSRF для веб-маршрутов не стоит.

Массовое присваивание без $fillable. Неверно: убрать из модели protected $fillable и вызвать Note::create($data). Фактический результат — исключение Add [title] to fillable property to allow mass assignment on [App\Models\Note]. и ответ 500. Исправление — перечислить разрешенные поля в $fillable (в Laravel 13 есть и вариант атрибутом класса #[Fillable(['title', 'body'])]). В нашем контроллере лишние поля уже отсекает validate(): он возвращает только проверенные ключи. $fillable — вторая линия защиты для кода, где в create() попадает весь запрос ($request->all()): тогда поле id=777 будет молча отброшено, и запись получит следующий обычный id.

Если не получилось — по симптому:

Симптом Причина Что сделать
No application encryption key has been specified. пустой APP_KEY в .env php artisan key:generate
SQLSTATE[HY000]: General error: 1 no such table: notes не применена миграция php artisan migrate
404 на /notes, хотя маршрут есть маршрут в api.php, а адрес без /api проверить php artisan route:list
419 на POST нет CSRF-токена для маршрута web.php @csrf в форме или маршрут в api.php
500 MassAssignmentException поле не указано в $fillable добавить поле в $fillable

Что нужно до production

Учебный пример выше специально минимален и не готов к публикации в интернете. Минимальный чек-лист:

  • APP_DEBUG=false. С true ответ на ошибку содержит путь к файлам и стек вызовов. С false в JSON остается только поле message.
  • Аутентификация и права. В примере создать заметку может любой. Для API обычно используют Sanctum (токены) и политики (Policies) для проверки прав на конкретную запись.
  • Ограничение частоты запросов через middleware throttle, особенно для POST.
  • Сырые запросы — только с параметрами. Eloquent и Query Builder экранируют значения, но whereRaw/DB::select со склейкой строки — нет: whereRaw('title = ?', [$title]), а не конкатенация.
  • Секреты в .env, файл не попадает в git; корень сайта на сервере — папка public/, а не корень проекта.

Когда выбирать Laravel, а когда нет

Ситуация Laravel уместен? Комментарий
Веб-приложение, SaaS, личный кабинет, внутренняя система да типовые задачи уже решены, быстрый старт
REST API для мобильного или SPA-клиента да api.php, Sanctum, валидация, ресурсы
Команда уже пишет на PHP да большой рынок пакетов и специалистов
Сайт-визитка, блог, контент без логики скорее нет CMS или генератор статических сайтов проще
Микросервис из пары эндпоинтов зависит микрофреймворк (Slim) может быть легче
Сложный корпоративный проект с долгим сроком жизни да, или Symfony оба подходят; Symfony гибче в сборке из компонентов
Много долгоживущих соединений (чат, стриминг) с оговорками нужны WebSocket-сервер (Reverb) или Octane; иногда проще другой стек

Laravel выбирают, когда важна скорость разработки и предсказуемая структура проекта. Цена — порог входа (много соглашений и «магии» фасадов) и накладные расходы на загрузку фреймворка по сравнению с маленьким скриптом на чистом PHP.

Версии и поддержка

Laravel создал Тейлор Отвелл, первая версия вышла в 2011 году. Сейчас мажорные версии выходят раз в год: Laravel 12 — в феврале 2025, Laravel 13 — в марте 2026. По политике проекта каждая мажорная версия получает исправления ошибок 18 месяцев и исправления безопасности 2 года. На сентябрь 2026 это значит: Laravel 13 (PHP 8.3-8.5) получает исправления ошибок до III квартала 2027 года и исправления безопасности до 17 марта 2028 года; у Laravel 12 исправления ошибок закончились 13 августа 2026 года, остались только исправления безопасности до 24 февраля 2027 года. Для нового проекта разумно брать Laravel 13, а проекты на 12 планировать к обновлению.

Выводы

  • Laravel — PHP-фреймворк для веб-приложений и API: маршруты, контроллеры, Eloquent, миграции, валидация и безопасные умолчания в одном каркасе.
  • Базовый цикл: маршрут -> контроллер -> модель Eloquent -> ответ; схема MVC здесь упрощение, а не обязательство.
  • Первые ошибки почти всегда одни и те же: 419 из-за CSRF в web.php, 422 из-за валидации, 500 из-за $fillable, пустого APP_KEY или непримененной миграции.
  • До production обязательны APP_DEBUG=false, аутентификация, ограничение частоты и секреты вне репозитория.
  • Laravel уместен, когда нужна быстрая разработка приложения со своей логикой; для простого контентного сайта удобнее CMS.

Где применяется / связь с практикой

Освойте тему на практике

Laravel — частый стек в вакансиях PHP-разработчиков: на нем пишут SaaS-сервисы, личные кабинеты, внутренние системы компаний и API для мобильных приложений. Если хотите пройти путь от учебного API, как в этой статье, до приложения с очередями, тестами и деплоем, посмотрите курс по Laravel в Otus. Отдельные темы можно разобрать на бесплатных открытых уроках.

FAQ

Нужно ли знать PHP перед изучением Laravel?
Да, хотя бы на уровне классов, пространств имен и Composer: Laravel активно использует ООП, и без этой базы код фреймворка выглядит как набор заклинаний.

Laravel — это бэкенд или фронтенд?
Бэкенд. Фронтенд можно отдавать шаблонами Blade, связкой Livewire или Inertia с React/Vue, а можно сделать Laravel только API для отдельного клиента.

Можно ли использовать Eloquent без остального Laravel?
Да, ORM распространяется отдельным пакетом illuminate/database, но в самостоятельном режиме его нужно настраивать вручную.

OTUS Журнал
Скидка 5% 12-19 октября на курсы (popup)
Бесплатные открытые уроки (поп-ап)