Документация Laravel 10.x
Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.
В других фреймворках пагинация может быть очень трудной. Мы надеемся, что подход Laravel к пагинации будет свежим взглядом. Пагинатор Laravel интегрирован с построителем запросов и ORM Eloquent и предоставляет удобную, простую в использовании пагинацию записей в базе данных без какой-либо конфигурации.
По умолчанию HTML, созданный пагинатором, совместим с фреймворком Tailwind CSS, однако также поддерживается пагинация Bootstrap.
Если вы используете представления пагинации 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',],
Есть несколько способов создания пагинации элементов. Самый простой - использовать метод paginate
в построителе запросов или 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
подсчитывает общее количество записей, соответствующих запросу, до извлечения записей из базы данных. Это делается для того, чтобы пагинатор знал, сколько всего страниц с записями. Однако, если вы не планируете показывать общее количество страниц в пользовательском интерфейсе вашего приложения, запрос на подсчет записей необязателен.
Поэтому, если вам нужно отображать простые ссылки "Next" и "Previous" в пользовательском интерфейсе вашего приложения, вы можете использовать метод simplePaginate
для выполнения одного эффективного запроса:
$users = DB::table('users')->simplePaginate(15);
Вы также можете создавать пагинацию для запросов Eloquent. В этом примере мы будем создавать пагинацию для модели App\Models\User
и указываем, что мы собираемся отображать 15 записей на странице. Как видите, синтаксис почти идентичен с пагинацией результатов построителя запросов:
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. Этот метод пагинации особенно подходит для больших наборов данных и интерфейсов пользователя с "бесконечным" прокручиванием.
В отличие от пагинации на основе смещения, которая включает номер страницы в строку запроса URL, созданную пагинатором, пагинация на основе курсора размещает строку "курсора" в строке запроса. Курсор - это закодированная строка, содержащая местоположение, с которого следующий запрос для пагинации должен начать пагинацию, и направление, в котором следует пагинировать:
http://localhost/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
Вы можете создать экземпляр пагинатора на основе курсора с помощью метода cursorPaginate
, предоставляемого построителем запросов. Этот метод возвращает экземпляр Illuminate\Pagination\CursorPaginator
:
$users = DB::table('users')->orderBy('id')->cursorPaginate(15);
После получения экземпляра пагинатора на основе курсора вы можете отобразить результаты пагинации, как обычно это делается при использовании методов paginate
и simplePaginate
. Для получения дополнительной информации о методах экземпляра пагинатора на основе курсора обратитесь к документации по методам экземпляра пагинатора на основе курсора.
Внимание Ваш запрос должен содержать клаузу "order by", чтобы воспользоваться пагинацией на основе курсора.
Для пояснения различий между пагинацией на основе смещения и пагинацией на основе курсора давайте рассмотрим несколько примеров SQL-запросов. Оба следующих запроса отобразят "вторую страницу" результатов для таблицы users
, упорядоченной по id
:
# Offset Pagination...select * from users order by id asc limit 15 offset 15; # Cursor Pagination...select * from users where id > 15 order by id asc limit 15;
Запрос пагинации на основе курсора предлагает следующие преимущества по сравнению с пагинацией на основе смещения:
Однако у пагинации на основе курсора есть следующие ограничения:
simplePaginate
, пагинация на основе курсора может использоваться только для отображения ссылок "Next" и "Previous" и не поддерживает создание ссылок с номерами страниц.null
не поддерживаются.Иногда вам может потребоваться создать экземпляр пагинатора вручную, передав ему массив элементов, которые у вас уже есть в памяти. Вы можете сделать это, создав экземпляр Illuminate\Pagination\Paginator
, Illuminate\Pagination\LengthAwarePaginator
или Illuminate\Pagination\CursorPaginator
, в зависимости от ваших потребностей.
Классам Paginator
и CursorPaginator
не требуется знать об общем количестве элементов в наборе результатов; однако из-за этого у этих классов нет методов для получения индекса последней страницы. LengthAwarePaginator
принимает почти те же аргументы, что и Paginator
; однако ему требуется количество общее количество элементов в наборе результатов.
Другими словами, Paginator
соответствует методу simplePaginate
в построителе запросов, CursorPaginator
соответствует методу cursorPaginate
, а LengthAwarePaginator
соответствует методу paginate
.
Внимание При создании экземпляра пагинатора вручную вы должны вручную "разделить" массив результатов, который вы передаете пагинатору. Если вы не уверены, как это сделать, ознакомьтесь с функцией PHP array_slice.
По умолчанию ссылки, создаваемые пагинатором, будут соответствовать 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() }}
Классы пагинаторов 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":[ { // Запись... }, { // Запись... } ]}
По умолчанию представления, рендерящие ссылки пагинации, совместимы с фреймворком Tailwind CSS. Однако, если вы не используете Tailwind, вы свободны определить свои собственные представления для отображения этих ссылок. При вызове метода links
на экземпляре пагинатора вы можете передать имя представления в качестве первого аргумента методу:
{{ $paginator->links('view.name') }} <!-- Passing additional data to the view... -->{{ $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'); }}
Laravel включает представления пагинации, созданные с использованием Bootstrap CSS. Чтобы использовать эти представления вместо представлений Tailwind по умолчанию, вы можете вызвать методы useBootstrapFour
или useBootstrapFive
пагинатора внутри метода boot
вашего класса App\Providers\AppServiceProvider
:
use Illuminate\Pagination\Paginator; /** * Загрузка любых служб приложения. */public function boot(): void{ Paginator::useBootstrapFive(); Paginator::useBootstrapFour();}
Каждый экземпляр пагинатора предоставляет дополнительную информацию о пагинации с помощью следующих методов:
Метод | Описание |
---|---|
$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) |
Преобразовать каждый элемент, используя обратный вызов. |
Каждый экземпляр пагинатора на основе курсора предоставляет дополнительную информацию о пагинации с помощью следующих методов:
Метод | Описание |
---|---|
$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 для заданного экземпляра курсора. |