Уроки курса
1 Основы синтаксиса PHP 8
60 мин
2 Функции и управляющие конструкции
60 мин
3 Объектно-ориентированное программирование на PHP
60 мин
4 Наследование, интерфейсы и полиморфизм
60 мин
5 Основы баз данных MySQL и работа через PDO
60 мин
6 Архитектурный паттерн MVC
60 мин
7 Введение в Laravel и настройка окружения
60 мин
8 Маршрутизация и контроллеры в Laravel
60 мин
9 Шаблонизатор Blade и создание интерфейса
60 мин
10 Миграции баз данных и Eloquent ORM
60 мин
11 Связи моделей в Eloquent — Настройка связей 'один …
60 мин
12 Аутентификация и защита маршрутов
60 мин
13 Разработка каталога товаров и категорий
60 мин
14 Реализация корзины покупок через сессии
60 мин
15 Оформление заказа и транзакции базы данных
60 мин
16 Интеграция платежной системы Stripe
60 мин
17 Интеграция платежной системы Vipps
60 мин
18 Разработка панели администратора
60 мин
19 Оптимизация и подготовка к production
60 мин
20 Деплой Laravel-приложения на сервер
60 мин
21 Основы PHP 8: Синтаксис, переменные и управляющие конструкции
60 мин
22 Функции и массивы в PHP 8
60 мин
23 Объектно-ориентированное программирование: Классы и объекты
60 мин
24 Продвинутое ООП: Наследование, интерфейсы и полиморфизм
60 мин
25 Основы баз данных: Проектирование БД и работа с …
60 мин
26 Взаимодействие PHP с MySQL через PDO
60 мин
27 Архитектура MVC и введение в фреймворк Laravel
60 мин
28 Маршрутизация и контроллеры в Laravel
60 мин
29 Шаблонизатор Blade: Создание пользовательского интерфейса
60 мин
30 Миграции и Eloquent ORM: Создание таблиц товаров
60 мин
31 Связи в Eloquent ORM: Отношения между моделями
60 мин
32 Аутентификация и авторизация пользователей
60 мин
33 Разработка каталога товаров: Вывод, фильтрация и пагинация
60 мин
34 Реализация корзины покупок с использованием сессий
60 мин
35 Оформление заказа: Работа с формами и валидация
60 мин
36 Транзакции базы данных: Сохранение заказа
60 мин
37 Интеграция платежной системы Stripe
60 мин
38 Интеграция платежной системы Vipps
60 мин
39 Создание панели администратора
60 мин
40 Подготовка к production и деплой приложения
60 мин
41 Основы PHP 8 и синтаксис
60 мин
42 Объектно-ориентированное программирование на PHP
60 мин
43 Продвинутое ООП и интерфейсы
60 мин
44 Основы баз данных и MySQL
60 мин
45 Архитектурный паттерн MVC
60 мин
46 Введение в Laravel и маршрутизация
60 мин
47 Шаблонизатор Blade и верстка интерфейса
60 мин
48 Миграции и структура базы данных
60 мин
49 Eloquent ORM и модели
60 мин
50 Отношения в Eloquent ORM
60 мин
51 Авторизация и защита маршрутов
60 мин
52 Создание каталога товаров
60 мин
53 Реализация корзины покупок
60 мин
54 Оформление заказа и транзакции БД
60 мин
55 Интеграция платежной системы Stripe
60 мин
56 Интеграция платежной системы Vipps
60 мин
57 Панель администратора: управление товарами
60 мин
58 Панель администратора: управление заказами
60 мин
59 Подготовка к production и деплой
60 мин
60 Запуск и тестирование готового интернет-магазина
60 мин

Разработка каталога товаров: Вывод, фильтрация и пагинация

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

Прогресс урока: 0%

Архитектура каталога: Жизненный цикл запроса

Каталог товаров — это лицо интернет-магазина. Реализация этой части проекта (Project-Based Learning) требует интеграции Маршрутизатора, Контроллера, Модели и Представления (MVC). Когда пользователь переходит по адресу /products, маршрутизатор вызывает метод index в ProductController. Задача контроллера — обратиться к модели Product, получить данные из базы, возможно, отфильтровать их и передать в шаблон Blade для генерации HTML.

Если в базе тысячи товаров, мы не можем вывести их все на одной странице — это убьет производительность сервера и браузера клиента. Здесь на помощь приходит пагинация (постраничная навигация). Laravel делает пагинацию невероятно простой. Вместо метода get(), который извлекает все записи, мы используем метод paginate(). Laravel сам вычислит смещение (OFFSET) и лимиты (LIMIT) для SQL-запроса на основе GET-параметра ?page= в URL.

php
// App\Http\Controllers\ProductController.php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller {
    public function index(Request $request) {
        // Создаем базовый запрос
        $query = Product::query();

        // Фильтрация по категории, если передан параметр category_id
        if ($request->has('category_id')) {
            $query->where('category_id', $request->input('category_id'));
        }

        // Решение проблемы N+1: жадная загрузка категорий
        $query->with('category');

        // Пагинация: 12 товаров на страницу
        $products = $query->paginate(12);

        return view('products.index', compact('products'));
    }
}

Проблема N+1 и Жадная загрузка (Eager Loading)

В коде выше вы заметили метод with('category'). Это критически важный момент для оптимизации производительности, который новички часто упускают. Представьте, что вы выводите 12 товаров на странице, и для каждого товара в шаблоне Blade вы пишете: {{ $product->category->name }}. Если вы не используете with(), Laravel сделает 1 запрос для получения 12 товаров, а затем 12 отдельных SQL-запросов для получения категории каждого товара. Итого: 1 + 12 = 13 запросов. Если товаров 100, будет 101 запрос. Это и есть проблема N+1.

Метод with('category') включает жадную загрузку (Eager Loading). Laravel сделает всего 2 запроса: первый — на получение 12 товаров, второй — на получение всех категорий, чьи ID присутствуют в этих 12 товарах (запрос вида SELECT * FROM categories WHERE id IN (...)). Затем фреймворк сам свяжет эти данные в памяти. Это колоссально снижает нагрузку на базу данных.

Какую проблему решает использование метода with() в Eloquent ORM?

Шаблонизатор Blade: Вывод товаров и ссылок пагинации

Получив объект Paginator в переменной $products, мы передаем его в представление. Blade предоставляет удобные директивы для работы с массивами и объектами. Мы используем директиву @foreach для перебора товаров и вывода их карточек.

Самое приятное в Laravel — это генерация HTML-кода для кнопок пагинации (1, 2, 3, Next, Previous). Для этого достаточно вызвать метод links() у объекта пагинатора: {{ $products->links() }}. По умолчанию Laravel использует стили Tailwind CSS для пагинации, но вы можете легко переключить их на Bootstrap в сервис-провайдере, если ваш проект использует этот CSS-фреймворк. Также важно помнить, что если вы используете фильтрацию (например, ?category_id=5), вам нужно сохранить эти GET-параметры в ссылках пагинации, используя метод appends().

html
<!-- resources/views/products/index.blade.php -->
<div class="grid">
    @foreach($products as $product)
        <div class="card">
            <h3>{{ $product->name }}</h3>
            <!-- Благодаря with('category') этот вызов не создает доп. SQL-запрос -->
            <p>Категория: {{ $product->category->name }}</p>
            <p>Цена: ${{ number_format($product->price, 2) }}</p>
            
            <form action="{{ route('cart.add') }}" method="POST">
                @csrf
                <input type="hidden" name="product_id" value="{{ $product->id }}">
                <button type="submit">В корзину</button>
            </form>
        </div>
    @endforeach
</div>

<!-- Вывод ссылок пагинации с сохранением параметров фильтрации -->
<div class="pagination-wrapper">
    {{ $products->appends(request()->query())->links() }}
</div>

Какой метод объекта Paginator в Blade-шаблоне используется для автоматической генерации HTML-кода кнопок постраничной навигации?