Пагинация и фильтры
Что такое пагинация
Пагинация — это разбивка большого списка на страницы. Если в таблице 10 000 постов, выводить их все сразу нельзя: это медленно и неудобно. Пагинация отдаёт только часть записей и ссылки для перехода между страницами.
Пагинация в Eloquent
$posts = Post::paginate(15);
Метод paginate возвращает объект LengthAwarePaginator, который содержит записи текущей страницы, общее количество, номер текущей страницы и ссылки.
Вывод в Blade:
@foreach ($posts as $post)
<article>{{ $post->title }}</article>
@endforeach
{{ $posts->links() }}
Простая пагинация
$posts = Post::simplePaginate(15);
Не считает общее количество записей — только «Назад» и «Вперёд». Быстрее, если точное число не важно.
Курсорная пагинация
$posts = Post::orderBy('id')->cursorPaginate(15);
Для очень больших таблиц. Вместо OFFSET использует курсор, поэтому работает за константное время.
Фильтры
Фильтры — это условия, которые пользователь задаёт через query-параметры:
$query = Post::query();
if ($request->filled('search')) {
$query->where('title', 'like', "%{$request->search}%");
}
if ($request->filled('status')) {
$query->where('status', $request->status);
}
$posts = $query->paginate(15)->withQueryString();
withQueryString() сохраняет параметры фильтра в ссылках пагинации.
Безопасная сортировка
Нельзя передавать имя колонки напрямую из запроса. Нужен белый список:
$sort = $request->get('sort', 'created_at');
$direction = $request->get('direction', 'desc');
$allowed = ['title', 'created_at', 'views'];
if (!in_array($sort, $allowed)) {
$sort = 'created_at';
}
$posts = Post::orderBy($sort, $direction)->paginate(15);
API-пагинация
return response()->json(Post::paginate(15));
Ответ содержит:
{
"data": [...],
"current_page": 1,
"last_page": 5,
"per_page": 15,
"total": 73,
"links": {...}
}