Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Постраничный вывод

Тысячу статей нельзя вывести на одной странице. Список делят на страницы, а 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').

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.