Постраничный вывод
Тысячу статей нельзя вывести на одной странице. Список делят на страницы, а Laravel сам считает количество записей, берёт нужную порцию и рисует ссылки.
paginate
Вместо get() вызывают paginate() с числом записей на странице:
public function index()
{
$posts = Post::latest()->paginate(15);
return view('posts.index', ['posts' => $posts]);
}Номер страницы Laravel берёт из адреса: /posts?page=2.
Вывод в шаблоне
Результат перебирают как обычную коллекцию, а метод links() выводит ссылки на страницы:
@foreach ($posts as $post)
<article>
<h2>{{ $post->title }}</h2>
</article>
@endforeach
{{ $posts->links() }}Сведения о страницах
<p>
Показаны записи {{ $posts->firstItem() }}–{{ $posts->lastItem() }}
из {{ $posts->total() }}
</p>| Метод | Что возвращает |
|---|---|
total() | Всего записей |
currentPage() | Номер текущей страницы |
lastPage() | Номер последней страницы |
hasMorePages() | Есть ли страницы дальше |
Сохранение фильтров
Если список отфильтрован, параметры фильтра должны остаться в ссылках на страницы. Это делает withQueryString():
$posts = Post::query()
->when($request->category, fn ($query, $category) => $query->where('category_id', $category))
->paginate(15)
->withQueryString();Ссылка на вторую страницу будет /posts?category=3&page=2.
Упрощённая пагинация
paginate() выполняет два запроса: за записями и за их общим числом. На больших таблицах подсчёт медленный. simplePaginate() показывает только «Назад» и «Вперёд» и обходится одним запросом:
$posts = Post::latest()->simplePaginate(15);Для бесконечной ленты подходит cursorPaginate() — он быстр на любой глубине.
Оформление ссылок
По умолчанию ссылки свёрстаны под Tailwind CSS. Чтобы изменить разметку, шаблоны выгружают в проект:
php artisan vendor:publish --tag=laravel-paginationОни появятся в resources/views/vendor/pagination.
Пагинация в API
Если вернуть результат paginate() из контроллера API, он превратится в JSON с записями и сведениями о страницах:
{
"data": [{ "id": 1, "title": "First post" }],
"current_page": 1,
"last_page": 7,
"per_page": 15,
"total": 100
}Обработка большой таблицы
Чтобы пройти по всем записям в фоновой задаче, их читают частями:
Post::where('is_published', true)->chunkById(500, function ($posts) {
foreach ($posts as $post) {
// обработка
}
});Частая ошибка
Пагинация без сортировки даёт непредсказуемый результат: база не обязана возвращать строки в одном и том же порядке, и запись может попасть на две страницы или не попасть ни на одну. Всегда задавайте порядок — latest(), orderBy('id').