Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x База данных: Пагинация

База данных: Пагинация

10.x 7 мар 2026 г.

#Введение

В других фреймворках пагинация может быть очень неудобной. Мы надеемся, что подход Laravel к пагинации станет для вас глотком свежего воздуха. Пагинатор Laravel интегрирован с query builder и Eloquent ORM и обеспечивает удобную и простую в использовании пагинацию записей базы данных без дополнительной настройки.

По умолчанию HTML, генерируемый пагинатором, совместим с фреймворком Tailwind CSS; однако также доступна поддержка пагинации Bootstrap.

#Tailwind JIT

Если вы используете стандартные представления пагинации Tailwind Laravel и движок Tailwind JIT, убедитесь, что ключ content в файле tailwind.config.js вашего приложения ссылается на представления пагинации Laravel, чтобы их классы Tailwind не удалялись при очистке:

content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
    './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
],

#Основное использование

#Пагинация результатов Query Builder

Существует несколько способов пагинации элементов. Самый простой — использовать метод paginate на query builder или Eloquent запросе. Метод paginate автоматически устанавливает "limit" и "offset" запроса в зависимости от текущей страницы, которую просматривает пользователь. По умолчанию текущая страница определяется значением параметра page в строке запроса HTTP. Это значение автоматически определяется Laravel и также автоматически вставляется в ссылки, генерируемые пагинатором.

В этом примере единственным аргументом, передаваемым методу paginate, является количество элементов, которые вы хотите отображать "на странице". В данном случае укажем, что хотим показывать по 15 элементов на страницу:

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Показать всех пользователей приложения.
     */
    public function index(): View
    {
        return view('user.index', [
            'users' => DB::table('users')->paginate(15)
        ]);
    }
}

#Простая пагинация

Метод paginate подсчитывает общее количество записей, соответствующих запросу, перед извлечением записей из базы данных. Это делается для того, чтобы пагинатор знал, сколько всего страниц с записями существует. Однако, если вы не планируете показывать общее количество страниц в интерфейсе вашего приложения, запрос подсчёта записей не нужен.

Поэтому, если вам нужно отображать только простые ссылки "Следующая" и "Предыдущая" в интерфейсе, вы можете использовать метод simplePaginate для выполнения одного эффективного запроса:

$users = DB::table('users')->simplePaginate(15);

#Пагинация результатов Eloquent

Вы также можете пагинировать запросы Eloquent. В этом примере мы пагинируем модель App\Models\User и указываем, что хотим отображать 15 записей на страницу. Как видите, синтаксис почти идентичен пагинации результатов query builder:

use App\Models\User;

$users = User::paginate(15);

Конечно, вы можете вызвать метод paginate после установки других ограничений в запросе, например, where:

$users = User::where('votes', '>', 100)->paginate(15);

Вы также можете использовать метод simplePaginate при пагинации моделей Eloquent:

$users = User::where('votes', '>', 100)->simplePaginate(15);

Аналогично, вы можете использовать метод cursorPaginate для курсорной пагинации моделей Eloquent:

$users = User::where('votes', '>', 100)->cursorPaginate(15);

#Несколько экземпляров пагинатора на странице

Иногда может потребоваться отобразить два отдельных пагинатора на одном экране вашего приложения. Однако, если оба пагинатора используют параметр строки запроса page для хранения текущей страницы, они будут конфликтовать. Чтобы решить эту проблему, вы можете передать имя параметра строки запроса, который хотите использовать для хранения текущей страницы пагинатора, третьим аргументом в методы paginate, simplePaginate и cursorPaginate:

use App\Models\User;

$users = User::where('votes', '>', 100)->paginate(
    $perPage = 15, $columns = ['*'], $pageName = 'users'
);

#Курсорная пагинация

В то время как paginate и simplePaginate создают запросы с использованием SQL-клаузы "offset", курсорная пагинация работает, формируя "where" условия, которые сравнивают значения упорядоченных столбцов в запросе, обеспечивая наиболее эффективную производительность базы данных среди всех методов пагинации Laravel. Этот метод пагинации особенно подходит для больших наборов данных и интерфейсов с "бесконечной" прокруткой.

В отличие от пагинации на основе offset, которая включает номер страницы в строке запроса URL, курсорная пагинация помещает в строку запроса строку "курсор". Курсор — это закодированная строка, содержащая позицию, с которой должен начинаться следующий запрос пагинации, и направление пагинации:

http://localhost/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0

Вы можете создать экземпляр курсорного пагинатора с помощью метода cursorPaginate, предоставляемого query builder. Этот метод возвращает экземпляр Illuminate\Pagination\CursorPaginator:

$users = DB::table('users')->orderBy('id')->cursorPaginate(15);

После получения экземпляра курсорного пагинатора вы можете отобразить результаты пагинации так же, как при использовании методов paginate и simplePaginate. Для получения дополнительной информации о методах экземпляра курсорного пагинатора обратитесь к документации по методам экземпляра курсорного пагинатора.

Внимание

Ваш запрос должен содержать клауза "order by", чтобы использовать курсорную пагинацию. Кроме того, столбцы, по которым упорядочивается запрос, должны принадлежать таблице, которую вы пагинируете.

#Курсорная пагинация против пагинации с offset

Чтобы проиллюстрировать различия между пагинацией с offset и курсорной пагинацией, рассмотрим примеры SQL-запросов. Оба следующих запроса отобразят "вторую страницу" результатов для таблицы users, упорядоченной по id:

# Пагинация с offset...
select * from users order by id asc limit 15 offset 15;

# Курсорная пагинация...
select * from users where id > 15 order by id asc limit 15;

Запрос курсорной пагинации имеет следующие преимущества по сравнению с пагинацией с offset:

  • Для больших наборов данных курсорная пагинация обеспечивает лучшую производительность, если столбцы "order by" индексированы. Это связано с тем, что клауза "offset" просматривает все ранее совпавшие данные.
  • Для наборов данных с частыми изменениями пагинация с offset может пропускать записи или показывать дубликаты, если результаты недавно добавлялись или удалялись со страницы, которую просматривает пользователь.

Однако курсорная пагинация имеет следующие ограничения:

  • Как и simplePaginate, курсорная пагинация может использоваться только для отображения ссылок "Следующая" и "Предыдущая" и не поддерживает генерацию ссылок с номерами страниц.
  • Требуется, чтобы упорядочивание было основано как минимум на одном уникальном столбце или комбинации уникальных столбцов. Столбцы с null значениями не поддерживаются.
  • Выражения в "order by" поддерживаются только если они имеют псевдонимы и добавлены в клауза "select".
  • Выражения с параметрами не поддерживаются.

#Ручное создание пагинатора

Иногда может потребоваться создать экземпляр пагинации вручную, передав ему массив элементов, которые уже есть в памяти. Вы можете сделать это, создав экземпляр Illuminate\Pagination\Paginator, Illuminate\Pagination\LengthAwarePaginator или Illuminate\Pagination\CursorPaginator в зависимости от ваших нужд.

Классы Paginator и CursorPaginator не требуют знания общего количества элементов в наборе результатов; однако из-за этого у этих классов отсутствуют методы для получения индекса последней страницы. LengthAwarePaginator принимает почти те же аргументы, что и Paginator, но требует подсчёта общего количества элементов в наборе.

Другими словами, Paginator соответствует методу simplePaginate query builder, CursorPaginator соответствует методу cursorPaginate, а LengthAwarePaginator соответствует методу paginate.

Внимание

При ручном создании экземпляра пагинатора вы должны вручную "вырезать" массив результатов, который передаёте пагинатору. Если вы не знаете, как это сделать, ознакомьтесь с функцией PHP array_slice.

#Настройка URL пагинации

По умолчанию ссылки, генерируемые пагинатором, соответствуют URI текущего запроса. Однако метод withPath пагинатора позволяет настроить URI, используемый при генерации ссылок. Например, если вы хотите, чтобы пагинатор генерировал ссылки вида http://example.com/admin/users?page=N, передайте /admin/users в метод withPath:

use App\Models\User;

Route::get('/users', function () {
    $users = User::paginate(15);

    $users->withPath('/admin/users');

    // ...
});

#Добавление значений в строку запроса

Вы можете добавить параметры в строку запроса ссылок пагинации с помощью метода appends. Например, чтобы добавить sort=votes к каждой ссылке пагинации, вызовите appends следующим образом:

use App\Models\User;

Route::get('/users', function () {
    $users = User::paginate(15);

    $users->appends(['sort' => 'votes']);

    // ...
});

Если вы хотите добавить все текущие параметры строки запроса к ссылкам пагинации, используйте метод withQueryString:

$users = User::paginate(15)->withQueryString();

#Добавление хэш-фрагментов

Если нужно добавить "хэш-фрагмент" к URL, генерируемым пагинатором, используйте метод fragment. Например, чтобы добавить #users в конец каждой ссылки пагинации, вызовите метод fragment так:

$users = User::paginate(15)->fragment('users');

#Отображение результатов пагинации

При вызове метода paginate вы получите экземпляр Illuminate\Pagination\LengthAwarePaginator, при вызове simplePaginate — экземпляр Illuminate\Pagination\Paginator, а при вызове cursorPaginate — экземпляр Illuminate\Pagination\CursorPaginator.

Эти объекты предоставляют несколько методов, описывающих набор результатов. Помимо этих вспомогательных методов, экземпляры пагинатора являются итераторами и могут использоваться в циклах как массивы. Таким образом, после получения результатов вы можете отобразить их и сгенерировать ссылки страниц с помощью Blade:

<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}

Метод links отобразит ссылки на остальные страницы набора результатов. Каждая из этих ссылок уже будет содержать правильную переменную строки запроса page. Помните, что HTML, генерируемый методом links, совместим с фреймворком Tailwind CSS.

При отображении ссылок пагинации текущий номер страницы показывается вместе со ссылками на три страницы до и после текущей. С помощью метода onEachSide вы можете контролировать, сколько дополнительных ссылок отображается с каждой стороны текущей страницы в среднем, скользящем окне ссылок, генерируемом пагинатором:

{{ $users->onEachSide(5)->links() }}

#Конвертация результатов в JSON

Классы пагинации Laravel реализуют интерфейс Illuminate\Contracts\Support\Jsonable и предоставляют метод toJson, поэтому конвертация результатов пагинации в JSON очень проста. Вы также можете вернуть экземпляр пагинатора из маршрута или действия контроллера, чтобы автоматически получить JSON:

use App\Models\User;

Route::get('/users', function () {
    return User::paginate();
});

JSON, возвращаемый пагинатором, будет содержать метаинформацию, такую как total, current_page, last_page и другие. Записи результатов доступны через ключ data в JSON-массиве. Вот пример JSON, созданного возвратом экземпляра пагинатора из маршрута:

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            // Record...
        },
        {
            // Record...
        }
   ]
}

#Настройка представления пагинации

По умолчанию представления, используемые для отображения ссылок пагинации, совместимы с фреймворком Tailwind CSS. Однако, если вы не используете Tailwind, вы можете определить свои собственные представления для отображения этих ссылок. При вызове метода links у экземпляра пагинатора вы можете передать имя представления в качестве первого аргумента:

{{ $paginator->links('view.name') }}

<!-- Передача дополнительных данных в представление... -->
{{ $paginator->links('view.name', ['foo' => 'bar']) }}

Однако самый простой способ настроить представления пагинации — экспортировать их в каталог resources/views/vendor вашего приложения с помощью команды vendor:publish:

php artisan vendor:publish --tag=laravel-pagination

Эта команда поместит представления в каталог resources/views/vendor/pagination вашего приложения. Файл tailwind.blade.php в этом каталоге соответствует стандартному представлению пагинации. Вы можете отредактировать этот файл для изменения HTML пагинации.

Если вы хотите назначить другой файл в качестве стандартного представления пагинации, вы можете вызвать методы defaultView и defaultSimpleView пагинатора в методе boot вашего класса App\Providers\AppServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Загрузка сервисов приложения.
     */
    public function boot(): void
    {
        Paginator::defaultView('view-name');

        Paginator::defaultSimpleView('view-name');
    }
}

#Использование Bootstrap

Laravel включает представления пагинации, построенные с использованием Bootstrap CSS. Чтобы использовать эти представления вместо стандартных Tailwind, вы можете вызвать методы useBootstrapFour или useBootstrapFive пагинатора в методе boot вашего класса App\Providers\AppServiceProvider:

use Illuminate\Pagination\Paginator;

/**
 * Загрузка сервисов приложения.
 */
public function boot(): void
{
    Paginator::useBootstrapFive();
    Paginator::useBootstrapFour();
}

#Методы экземпляров Paginator / LengthAwarePaginator

Каждый экземпляр пагинатора предоставляет дополнительную информацию о пагинации через следующие методы:

Метод Описание
$paginator->count() Получить количество элементов на текущей странице.
$paginator->currentPage() Получить номер текущей страницы.
$paginator->firstItem() Получить номер первой записи в результатах.
$paginator->getOptions() Получить опции пагинатора.
$paginator->getUrlRange($start, $end) Создать диапазон URL пагинации.
$paginator->hasPages() Определить, достаточно ли элементов для разделения на несколько страниц.
$paginator->hasMorePages() Определить, есть ли ещё элементы в хранилище данных.
$paginator->items() Получить элементы текущей страницы.
$paginator->lastItem() Получить номер последней записи в результатах.
$paginator->lastPage() Получить номер последней доступной страницы. (Недоступно при использовании simplePaginate).
$paginator->nextPageUrl() Получить URL следующей страницы.
$paginator->onFirstPage() Определить, находится ли пагинатор на первой странице.
$paginator->perPage() Количество элементов, отображаемых на странице.
$paginator->previousPageUrl() Получить URL предыдущей страницы.
$paginator->total() Определить общее количество совпадающих элементов в хранилище данных. (Недоступно при использовании simplePaginate).
$paginator->url($page) Получить URL для указанного номера страницы.
$paginator->getPageName() Получить имя переменной строки запроса, используемой для хранения номера страницы.
$paginator->setPageName($name) Установить имя переменной строки запроса, используемой для хранения номера страницы.
$paginator->through($callback) Преобразовать каждый элемент с помощью callback-функции.

#Методы экземпляров Cursor Paginator

Каждый экземпляр курсорного пагинатора предоставляет дополнительную информацию о пагинации через следующие методы:

Метод Описание
$paginator->count() Получить количество элементов на текущей странице.
$paginator->cursor() Получить текущий экземпляр курсора.
$paginator->getOptions() Получить опции пагинатора.
$paginator->hasPages() Определить, достаточно ли элементов для разделения на несколько страниц.
$paginator->hasMorePages() Определить, есть ли ещё элементы в хранилище данных.
$paginator->getCursorName() Получить имя переменной строки запроса, используемой для хранения курсора.
$paginator->items() Получить элементы текущей страницы.
$paginator->nextCursor() Получить экземпляр курсора для следующего набора элементов.
$paginator->nextPageUrl() Получить URL следующей страницы.
$paginator->onFirstPage() Определить, находится ли пагинатор на первой странице.
$paginator->onLastPage() Определить, находится ли пагинатор на последней странице.
$paginator->perPage() Количество элементов, отображаемых на странице.
$paginator->previousCursor() Получить экземпляр курсора для предыдущего набора элементов.
$paginator->previousPageUrl() Получить URL предыдущей страницы.
$paginator->setCursorName() Установить имя переменной строки запроса, используемой для хранения курсора.
$paginator->url($cursor) Получить URL для указанного экземпляра курсора.