Разработка веб-приложений с использованием программных платформ

Тема 3. Основы Laravel

Разработка веб-приложений с использованием программных платформ

План лекции

Основные вопросы

  • Установка и структура проекта
  • MVC и цикл HTTP-запроса
  • Маршруты и контроллеры
  • Blade и HTML-форма
  • SQLite, миграции и Eloquent
  • Валидация и диагностика

Цели лекции

  • Запустить новый проект Laravel
  • Проследить запрос до ответа
  • Создать модель и таблицу posts
  • Вывести и сохранить посты
  • Обработать ошибки формы
  • Проверить готовность мини-блога
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Версия и границы темы

На 1 сентября 2026 года

  • Laravel 13 выпущен 17 марта 2026 года
  • Требуется PHP 8.3 или новее
  • Поддерживаются PHP 8.3-8.5
  • В примерах используется Laravel 13

В этой лекции

  • Один серверный Blade-интерфейс
  • Два маршрута для Post
  • SQLite и одна миграция
  • Inline validation в контроллере
  • Без аутентификации и REST API
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Что нужно до установки

php -v
composer --version
php -m
Компонент Для чего нужен
PHP 8.3-8.5 выполнение приложения
Composer 2.x зависимости и Laravel Installer
PDO SQLite локальная база данных
Терминал команды Installer и Artisan
Браузер интерфейс и DevTools

Node.js не нужен для минимального PHP-only примера без Vite.

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

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

composer global require laravel/installer
laravel new mini-blog
cd mini-blog
  • laravel/installer ставится глобально для текущего пользователя
  • laravel new создает каркас и устанавливает зависимости
  • В интерактивных вопросах выбираем SQLite
  • Sail и Docker не добавляем в этот локальный сценарий
  • Все следующие команды выполняются из mini-blog
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Два режима запуска

Минимальный пример

php artisan serve
  • Достаточно для Blade без @vite
  • Приложение доступно на локальном адресе
  • Процесс останавливается сочетанием Ctrl+C

Полный frontend workflow

npm install && npm run build
composer run dev
  • Нужен, когда проект использует Vite и frontend-ресурсы
  • Требует Node.js и npm
  • composer run dev запускает процессы разработки проекта
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Окружение и секреты

Файлы

  • .env.example хранит образец переменных
  • .env содержит настройки конкретной машины
  • Laravel читает окружение через конфигурацию
  • Новый проект генерирует локальный APP_KEY

Правила

  • Не коммитить .env
  • Не хранить пароли и токены в Git
  • Использовать APP_DEBUG=true только локально
  • Для общего шаблона обновлять .env.example
APP_ENV=local
APP_DEBUG=true
DB_CONNECTION=sqlite
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Структура прикладного кода

Путь Назначение в мини-блоге
app/Http/Controllers прием запроса и выбор ответа
app/Models Eloquent-модели предметных данных
routes/web.php маршруты браузерного интерфейса
resources/views Blade-шаблоны HTML
database/migrations изменения схемы базы данных
  • Пространства имен повторяют структуру app
  • Сгенерированные файлы сначала читают, затем изменяют
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Структура выполнения

Веб-часть

  • public/index.php принимает веб-запрос
  • public является корнем веб-сервера
  • Остальные исходники не должны раздаваться напрямую

Состояние и диагностика

  • storage содержит runtime-файлы приложения
  • storage/logs/laravel.log хранит журнал Laravel
  • database/database.sqlite содержит локальную SQLite-базу
  • bootstrap запускает и настраивает приложение
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Роли MVC в примере

Model

  • Post представляет записи таблицы posts
  • Eloquent строит запросы к базе
  • Модель задает допустимые поля массового заполнения

View

  • Blade получает подготовленные данные
  • Шаблон создает HTML-ответ
  • {{ }} экранирует вывод

Controller

  • Принимает объект запроса
  • Координирует модель и представление
  • Возвращает View или перенаправление
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Цикл запроса Laravel

browser
   -> public/index.php
   -> bootstrap приложения
   -> middleware и router
   -> PostController
   -> Eloquent -> SQLite
   -> Blade
   -> HTTP response -> browser
  • Middleware работает до или после контроллера
  • Router сопоставляет HTTP-метод и URI с обработчиком
  • Не каждый запрос обращается к базе или Blade
  • В нашем GET /posts задействована вся показанная цепочка
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Что дает routes/web.php

Группа web

  • Назначается маршрутам файла по умолчанию
  • Поддерживает cookies и состояние сессии
  • Делает доступными flash-данные и старый ввод
  • Проверяет CSRF-токен для изменяющих запросов

Следствие для форм

  • GET читает страницу
  • POST создает данные
  • Для POST, PUT, PATCH, DELETE нужен @csrf
  • Метод и URI должны совпасть с маршрутом
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Маршрут и ограничение параметра

use Illuminate\Support\Facades\Route;

Route::get('/demo/posts/{postId}', function (string $postId) {
    return "Post {$postId}";
})->whereNumber('postId')
  ->name('posts.show-demo');
  • get задает допустимый HTTP-метод
  • {postId} извлекает сегмент URI
  • whereNumber принимает только цифры
  • name отделяет имя маршрута от его URI
  • Это отдельная демонстрация вне маршрутов мини-блога
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Маршруты мини-блога

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

Route::get('/posts', [PostController::class, 'index'])
    ->name('posts.index');

Route::post('/posts', [PostController::class, 'store'])
    ->name('posts.store');
php artisan route:list --except-vendor
  • Один URI может иметь разные обработчики для GET и POST
  • Blade строит адрес через route('posts.store')
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Генерация файлов примера

php artisan make:model Post -m
php artisan make:controller PostController

Первая команда

  • Создает app/Models/Post.php
  • Флаг -m создает миграцию для posts
  • Имя таблицы выводится из имени модели

Вторая команда

  • Создает контроллер в app/Http/Controllers
  • Не добавляет маршруты автоматически
  • Методы index и store пишем явно
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

SQLite в новом Laravel 13

Значения по умолчанию

  • Свежий проект использует SQLite
  • Соединение задает DB_CONNECTION=sqlite
  • База находится в database/database.sqlite
  • Отдельный сервер базы не требуется

Что проверить

  • Файл базы существует и доступен на запись
  • В PHP включено расширение PDO SQLite
  • Приложение читает нужный .env
  • Миграции применены к текущему окружению
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Миграция таблицы posts

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Управление миграциями

php artisan migrate
php artisan migrate:status

up

  • Применяет изменение схемы
  • Создает таблицу posts
  • Состояние записывается в таблице миграций

down

  • Описывает обратное изменение
  • Используется при rollback
  • Удаление таблицы уничтожает ее данные

php artisan migrate:rollback применяйте осторожно и только локально, когда понимаете состав последнего пакета миграций.

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Модель Post

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title',
        'body',
    ];
}
  • Eloquent связывает Post с таблицей posts
  • $fillable разрешает массовое заполнение только указанных полей
  • Это граница mass assignment, но не замена validation
  • В create() передаем только массив $validated
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Чтение и создание через Eloquent

$posts = Post::query()
    ->latest()
    ->get();

$post = Post::create([
    'title' => 'Первый пост',
    'body' => 'Текст первого поста',
]);

Чтение

  • query() начинает построение запроса
  • latest() сортирует по created_at от новых к старым
  • get() выполняет запрос и возвращает коллекцию

Создание

  • create() массово заполняет модель
  • Поля сверяются с $fillable
  • Eloquent устанавливает timestamps
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Тонкий PostController

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index(): View
    {
        return view('posts.index', [
            'posts' => Post::query()->latest()->get(),
        ]);
    }

    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'body' => ['required', 'string', 'max:10000'],
        ]);

        Post::create($validated);

        return redirect()->route('posts.index')
            ->with('status', 'Пост добавлен');
    }
}
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Почему контроллер остается тонким

index

  • Получает коллекцию постов
  • Передает ее в posts.index
  • Объявляет результат как View

store

  • Валидирует только два входных поля
  • Передает $validated модели
  • Возвращает RedirectResponse
  • Кладет status во flash-сессию
  • SQL, разметка и ручная работа с CSRF в контроллер не попали
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Обычный сбой валидации

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

Браузерная форма

  • Laravel перенаправляет назад
  • Ошибки попадают в error bag
  • Введенные значения доступны через old()
  • Запись в базе не создается

XHR или JSON-запрос

  • Laravel возвращает HTTP 422
  • Ответ содержит ошибки по полям
  • Клиент сам решает, как их показать
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Post/Redirect/Get после успеха

POST /posts
   -> validate
   -> INSERT
   -> 302 redirect to posts.index
GET /posts
   -> render updated list
  • Успешный POST не возвращает страницу списка напрямую
  • Redirect меняет следующий запрос на GET
  • Обновление страницы повторяет GET, а не вставку
  • Flash status живет до следующего запроса
  • Ошибка валидации использует другой redirect back
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Минимальный Blade-layout

{{-- resources/views/layouts/app.blade.php --}}
<!doctype html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@yield('title', 'Мини-блог')</title>
</head>
<body>
    <main>
        @yield('content')
    </main>
</body>
</html>
  • Layout содержит общую HTML-оболочку
  • @yield отмечает место дочернего содержимого
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Форма создания поста

<form method="POST" action="{{ route('posts.store') }}">
    @csrf
    <label for="title">Заголовок</label>
    <input id="title" name="title" value="{{ old('title') }}">
    @error('title') <p>{{ $message }}</p> @enderror
    <label for="body">Текст</label>
    <textarea id="body" name="body">{{ old('body') }}</textarea>
    @error('body') <p>{{ $message }}</p> @enderror
    <button type="submit">Добавить</button>
</form>
  • @csrf добавляет скрытый токен
  • route() использует имя маршрута, а не жесткий URL
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Страница списка постов

{{-- resources/views/posts/index.blade.php --}}
@extends('layouts.app')

@section('title', 'Посты')

@section('content')
    <h1>Посты</h1>

    @if (session('status'))
        <p>{{ session('status') }}</p>
    @endif

    @include('posts._form')

    @forelse ($posts as $post)
        <article>
            <h2>{{ $post->title }}</h2>
            <p>{{ $post->body }}</p>
        </article>
    @empty
        <p>Постов пока нет.</p>
    @endforelse
@endsection
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Экранирование в Blade

<h2>{{ $post->title }}</h2>
<p>{{ $post->body }}</p>

{{ }}

  • Blade вызывает экранирование на основе htmlspecialchars
  • HTML-теги из пользовательского текста не исполняются
  • Это обычный выбор для данных формы

{!! !!}

  • Выводит значение без экранирования
  • Не использовать для пользовательских данных
  • Validation длины не превращает HTML в безопасный
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Порядок сборки мини-блога

  1. Создать проект и проверить .env
  2. Сгенерировать Post с миграцией
  3. Описать up() и down(), выполнить migrate
  4. Задать $fillable в модели
  5. Создать контроллер и два named route
  6. Добавить layout, форму и список
  7. Проверить успешный и ошибочный сценарии

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

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Инструменты диагностики

В терминале и файлах

  • php artisan route:list --except-vendor
  • php artisan migrate:status
  • storage/logs/laravel.log
  • вывод процесса php artisan serve

В браузере

  • адрес и HTTP-метод запроса
  • вкладка Network в DevTools
  • status code и response body
  • поля формы и redirect chain
  • APP_DEBUG=true допустим только в локальной среде
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Частые коды и причины

Код Что проверить сначала
404 URI, HTTP-метод, ограничение параметра, route:list
419 наличие @csrf, cookies, срок сессии
422 правила validation и поля JSON/XHR-запроса
500 laravel.log, stack trace локально, подключение к БД
  • Для обычной HTML-формы validation чаще виден как redirect назад
  • Ошибка no such table: posts означает, что нужная миграция не применена
  • Mass assignment exception требует проверить $fillable и входной массив
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Готовность к лабораторной 1

Установка, структура, маршруты и Blade

  • Проект mini-blog запускается через php artisan serve
  • Студент объясняет назначение семи основных путей проекта
  • GET /posts связан с PostController@index
  • POST /posts связан с PostController@store
  • Оба маршрута имеют имена и видны в route:list
  • Layout и страница списка открываются без Vite
  • В форме есть method="POST" и @csrf
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Готовность к лабораторной 2

SQLite, Eloquent и обработка формы

  • Миграция создает posts и корректно удаляет таблицу в down()
  • migrate:status показывает примененную миграцию
  • Post содержит $fillable для title и body
  • Валидный POST создает запись один раз
  • Невалидный POST показывает ошибки и сохраняет старый ввод
  • После успеха работает PRG и flash status
  • Пользовательский текст выводится через {{ }}
  • Причины 404, 419, 422 и 500 проверяются по плану
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Что остается для лекции 4

  • Полноценная аутентификация и starter kits
  • Авторизация через Gates и Policies
  • Form Requests вместо inline validation
  • REST API и отдельные JSON-контракты
  • Файлы и storage
  • Cache
  • Tests
  • Deployment

В лекции 3 строим базовую серверную цепочку. Расширения добавляются после того, как она понятна и работает.

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Резюме

Каркас приложения

  • public/index.php принимает запрос
  • Router выбирает контроллер
  • Blade формирует HTML
  • Группа web дает сессию и CSRF

Данные и форма

  • Миграция версионирует схему
  • Eloquent работает с Post
  • Validation проверяет входные поля
  • PRG завершает успешный POST

Безопасная разработка

  • .env и секреты остаются вне Git
  • $fillable ограничивает mass assignment
  • {{ }} экранирует пользовательский текст
  • Диагностика начинается с status code
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Вопросы для самопроверки: устройство

Установка и структура

  1. Какие версии PHP поддерживает Laravel 13?
  2. Когда достаточно php artisan serve?
  3. Чем различаются .env и .env.example?
  4. Какие файлы нельзя хранить в Git?

Запрос и MVC

  1. Как запрос проходит от браузера до ответа?
  2. Как разделены роли Model, View и Controller?
  3. Что дает группа middleware web?
  4. Зачем маршруту задают имя?
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Вопросы для самопроверки: мини-блог

Данные

  1. Что делают методы up() и down()?
  2. Почему $fillable не заменяет validation?
  3. Когда Eloquent выполняет запрос с get()?
  4. Почему в Post::create() передают $validated?

Форма и ошибки

  1. Что происходит при сбое $request->validate()?
  2. Для чего форме нужен @csrf?
  3. Как PRG защищает от повторной вставки?
  4. С чего начать проверку ошибок 419 и 500?
Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Ресурсы: версия и устройство

Версия и установка

Архитектура

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Ресурсы: HTTP и представление

Маршруты и контроллеры

Формы и Blade

Лекция 3. Основы Laravel
Разработка веб-приложений с использованием программных платформ

Ресурсы: данные

Схема базы

Модели и запросы

Лекция 3. Основы Laravel

Лекция 3, 90 минут. Свяжите Laravel с HTTP, MVC, PHP, формами и PDO из лекций 1-2. Цель занятия: собрать минимальный мини-блог и подготовить студентов к первым двум лабораторным работам по Laravel.

Отведите около 20 минут на устройство Laravel, 45 минут на сквозной пример, 15 минут на диагностику и лабораторные, 10 минут на повторение.

Зафиксируйте дату версии. Документацию следует открывать в ветке 13.x, а не считать номер версии вечным.

Проверьте наличие `pdo_sqlite`. Если расширения нет, миграция завершится ошибкой еще до работы контроллера.

Выполните команды заранее или покажите короткую живую установку. Не переключайтесь на Sail: это другой способ организации среды.

Покажите, что выбранный далее layout не содержит `@vite`, поэтому для лекционного примера достаточно `php artisan serve`.

Откройте `.gitignore` и убедитесь вместе со студентами, что `.env` исключен. Не выводите реальные ключи на экран.

Быстро откройте каждый путь в редакторе. Попросите студентов заранее назвать, где они будут искать маршрут, модель и HTML.

Подчеркните, что веб-сервер направляет запрос в `public/index.php`, а не в `routes/web.php` напрямую.

Не называйте контроллер мозгом приложения. Его задача здесь узкая: связать HTTP, запрос модели и ответ.

Пройдите по цепочке дважды: сначала для GET списка, затем для POST формы. Во втором случае отметьте CSRF и валидацию.

Свяжите сессию сразу с тремя вещами: CSRF-токеном, ошибками валидации и `old()` после возврата к форме.

Сравните `/demo/posts/15` и `/demo/posts/new`: второй адрес не пройдет числовое ограничение и даст 404.

В выводе `route:list` найдите методы, URI, имена и действия обоих маршрутов.

После генерации покажите `git diff` или дерево проекта. Artisan дает заготовки, но не принимает архитектурные решения за разработчика.

Покажите файл SQLite в дереве проекта. Не открывайте его как текстовый файл: содержимое двоичное.

Сопоставьте `string` и `text` с ограничениями формы. `timestamps()` добавляет `created_at` и `updated_at`.

Покажите `migrate:status` до и после `migrate`. Не используйте `migrate:fresh` в проекте с нужными данными.

Спросите, почему нельзя передавать в `create()` весь `$request->all()`. Лишнее поле не должно попасть в массовое заполнение.

Уточните, что реальный контроллер ниже передает в `create()` результат валидации, а не вручную составленный учебный массив.

Проследите четыре действия `store`: получить запрос, проверить данные, создать запись, вернуть перенаправление.

Сравните роли с MVC-слайдом. Контроллер координирует шаги, но не формирует HTML и не пишет SQL вручную.

Отправьте пустую форму. Это штатная ветка приложения, а не исключительная поломка сервера.

После создания поста обновите страницу. Объясните, почему браузер не предлагает повторно отправить форму.

Сначала откройте страницу без CSS. Цель примера состоит в серверной цепочке, а не в оформлении интерфейса.

В DevTools откройте payload POST-запроса и найдите `_token`, `title` и `body`. Сам токен не нужно читать вслух или сохранять.

Создайте первый пост и покажите flash-сообщение. После следующего запроса оно исчезнет, а запись останется в SQLite.

Введите в заголовок `<script>alert(1)</script>` и покажите его как текст. Не заменяйте `{{ }}` на сырой вывод ради демонстрации.

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

Разберите одну ошибку от внешнего симптома к источнику: status code, маршрут, журнал, строка приложения.

Не предлагайте сразу очищать все кеши или пересоздавать проект. Сначала установите код ответа и воспроизведите конкретный запрос.

Используйте список как приемочный чек-лист первой лабораторной, а не как дополнительную теорию.

Попросите показать оба сценария формы. Наличие записи в таблице без корректной обработки ошибки еще не означает готовность работы.

Не начинайте установку starter kit в этом проекте на занятии. Она изменит frontend workflow и отвлечет от базового цикла запроса.

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

Просите не перечислить термины, а объяснить путь конкретного `GET /posts`.

Выберите по одному вопросу из каждой группы. Остальные оставьте для самостоятельной проверки перед лабораторной.

Откройте оглавление документации 13.x и покажите, как перейти от метода из примера к полному справочному разделу.