Настройка
В некоторых фреймворках страничный вывод может быть большой проблемой. Страничный вывод в Laravel интегрирован с построителем запросов и Eloquent ORM и обеспечивает удобный, простой в использовании вывод результатов БД. Генерируемый HTML-код совместим с CSS-фреймворком Bootstrap.
Основы использования
Страничный вывод выборки из БД
Есть несколько способов разделения данных на страницы. Самый простой — используя метод PHPpaginate()
на объекте-конструкторе запросов или на запросе Eloquent. Метод PHPpaginate()
автоматически позаботится о задании правильных пределов и промежутков на основе текущей просматриваемой пользователем страницы. По умолчанию текущая страница определяется по значению аргумента ?page в HTTP-запросе. Само собой, Laravel автоматически определяет это значение, и так же автоматически вставляет его в ссылки, генерируемые для страничного вывода.
В этом примере единственный аргумент метода PHPpaginate()
— число элементов на одной странице. Давайте укажем, что мы хотим выводить по 15 элементов на страницу:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
//для версии 5.2 и ранее:
//use DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Вывести всех пользователей приложения.
*
* @return Response
*/
public function index()
{
$users = DB::table('users')->paginate(15);
return view('user.index', ['users' => $users]);
}
}
На данный момент операции страничного вывода, которые используют оператор PHPgroupBy
, не могут эффективно выполняться в Laravel. Если вам необходимо использовать PHPgroupBy
для постраничного набора результатов, рекомендуется делать запрос в БД и создавать экземпляр страничного вывода вручную.
Если вам необходимо вывести для страничного представления только ссылки «Далее» и «Назад», вы можете использовать метод PHPsimplePaginate()
для более эффективных запросов. Для больших наборов данных очень полезно, когда вам не надо отображать номер каждой страницы в вашем представлении:
$users = DB::table('users')->simplePaginate(15);
Страничный вывод запросов Eloquent
Можно также делать постраничный вывод запросов Eloquent. В этом примере мы разобьём на страницы модель User по 15 элементов на странице. Как видите, синтаксис практически совпадает со страничным выводом выборки из БД:
$users = App\User::paginate(15);
Разумеется, вы можете вызвать PHPpaginate()
после задания других условий запроса, таких как where:
$users = User::where('votes', '>', 100)->paginate(15);
Также вы можете использовать метод PHPsimplePaginate()
моделей Eloquent:
$users = User::where('votes', '>', 100)->simplePaginate(15);
Ручное создание экземпляра страничного вывода
Иногда необходимо создать экземпляр страничного вывода вручную, передав ему массив данных. Это можно сделать создав либо экземпляр Illuminate\Pagination\Paginator, либо экземпляр Illuminate\Pagination\LengthAwarePaginator, в зависимости от ситуации.
Классу Paginator не надо знать общее количество элементов в конечном наборе, и поэтому класс не должен иметь методы для получения индекса последней страницы. LengthAwarePaginator принимает почти те же аргументы, что и Paginator, но ему требуется общее количество элементов в конечном наборе.
Другими словами, Paginator соответствует методу PHPsimplePaginate()
на конструкторе запросов и Eloquent, а LengthAwarePaginator соответствует методу PHPpaginate()
.
При ручном создании экземпляра страничного вывода вы должны вручную «поделить» передаваемый в него массив результатов. Если вы не знаете, как это сделать, используйте PHP-функцию array_slice.
Отображение результатов страничного вывода
При вызове методов PHPpaginate()
и PHPsimplePaginate()
на конструкторе запросов или запросе Eloquent вы получите экземпляр страничного вывода. Для метода PHPpaginate()
это будет экземпляр Illuminate\Pagination\LengthAwarePaginator. А для метода PHPsimplePaginate()
это будет экземпляр Illuminate\Pagination\Paginator. Эти объекты предоставляют несколько методов для вывода конечного набора. В дополнение к этим вспомогательным методам экземпляры страничного вывода — итераторы, к ним можно обращаться как к массивам. Итак, когда вы получили результаты, вы можете вывести их и создать ссылки на страницы с помощью Blade:
<div class="container">
@foreach ($users as $user)
{{ $user->name }}
@endforeach
</div>
{{ $users->links() }}
//для версии 5.1 и ранее:
//{!! $users->render() !!}
добавлено в 5.0 ()
Метод PHPlinks()
(для версии 5.1 и ранее PHPrender()
) выведет ссылки на остальные страницы в конечном наборе. Каждая из этих ссылок уже будет содержать правильную переменную строки запроса page. Помните, сгенерированный методом PHPlinks()
HTML-код совместим с CSS-фреймворком Bootstrap.
Настройка URI для вывода ссылок
Настроить URI для вывода ссылок на страницы можно с помощью метода PHPsetPath()
. Например, если вы хотите получить ссылки вида http://example.com/custom/url?page=N, вам надо передать custom/url в метод PHPsetPath()
:
Route::get('users', function () {
$users = App\User::paginate(15);
$users->setPath('custom/url');
//
});
Вы можете добавить параметры запросов к ссылкам страниц с помощью метода PHPappends()
. Например, чтобы добавить &sort=votes к каждой страничной ссылке, вам надо вызвать PHPappends()
вот так:
{{ $users->appends(['sort' => 'votes'])->links() }}
//для версии 5.1 и ранее:
//{!! $users->appends(['sort' => 'votes'])->render() !!}
Код выше создаст ссылки наподобие:
http://example.com/something?page=2&sort=votes
Если вы хотите добавить «хэш-фрагмент» в URL-адреса страничного вывода, вы можете использовать метод PHPfragment()
. Например, чтобы добавить #foo к каждой страничной ссылке, вам надо вызвать PHPfragment()
вот так:
{{ $users->fragment('foo')->links() }}
//для версии 5.1 и ранее:
//{!! $users->fragment('foo')->render() !!}
Вызов этого метода сгенерирует URL-адреса наподобие:
http://example.com/something?page=2#foo
Преобразование в JSON
Классы страничного вывода Laravel реализуют контракт интерфейса Illuminate\Contracts\Support\Jsonable и предоставляют метод PHPtoJson()
, поэтому можно очень легко конвертировать ваш страничный вывод в JSON. Вы также можете преобразовать экземпляр страничного вывода в JSON, просто вернув его из маршрута или действия контроллера.
Route::get('users', function () {
return App\User::paginate();
});
JSON-форма экземпляра будет включать некоторые «мета-данные», такие как total, current_page, last_page и другие. Данные экземпляра будут доступны через ключ data в массиве JSON. Вот пример JSON, созданного при помощи возврата экземпляра страничного вывода из маршрута:
{
"total": 50,
"per_page": 15,
"current_page": 1,
"last_page": 4,
"next_page_url": "http://laravel.app?page=2",
"prev_page_url": null,
"from": 1,
"to": 15,
"data":[
{
// Объект вывода
},
{
// Объект вывода
}
]
}
добавлено в 5.3 ()
Настройка представления страничного вывода
По умолчанию отрисованные представления для отображения ссылок страничного вывода совместимы с CSS-фреймворком Bootstrap. Но если вы не используете Bootstrap, вы можете определить свои собственные представления для отрисовки этих ссылок. При вызове метода PHPlinks()
на экземпляре страничного вывода передайте первым аргументом имя представления:
{{ $paginator->links('view.name') }}
Но самый простой способ изменить представления страничного вывода — экспортировать их в ваш каталог resources/views/vendor с помощью команды shvendor:publish
:
shphp artisan vendor:publish --tag=laravel-pagination
Эта команда поместит представления в папку resources/views/vendor/pagination. Файл default.blade.php в этой папке является стандартным представлением страничного вывода. Просто отредактируйте этот файл, чтобы изменить HTML страничного вывода.
Методы экземпляра страничного вывода
Каждый экземпляр страничного вывода предоставляет дополнительную информацию с помощью этих методов:
PHP$results->count()
PHP$results->currentPage()
PHP$results->firstItem()
(для версии 5.2 и выше)PHP$results->hasMorePages()
PHP$results->lastItem()
(для версии 5.2 и выше)PHP$results->lastPage()
(недоступен при использовании simplePaginate)PHP$results->nextPageUrl()
PHP$results->perPage()
PHP$results->previousPageUrl()
PHP$results->total()
(недоступен при использовании simplePaginate)PHP$results->url($page)
Комментарии (8)
А подскажите пожалуйста как сделать ссылки такого вида http://localhost/page-1 или например такого http://localhost/page/1?
Laravel 5.2.42. Сделал так: создал свой класс пагинации на основе \Illuminate\Pagination\LengthAwarePaginator и в ней изменил public function url($page) под себя.
А так же в контроллере беру данные о странице и из них строю запросы, а потом передаю в пагинатор, который и создаёт ссылки.
Ну и во вьюхе:
Роуты:
В итоге у меня получилось что на главной всегда первая страница, а при переходе на другую адрес уже становится site.ru/blog/page/2. Можно убрать blog/ и тогда получится просто site.ru/page/1 По-хорошему может даже надо разделить контроллеры со страницами и бе3. В планах ещё изучить render() и сделать свой. Может я не совсем правильно делаю, но пока только учусь...
Здравствуйте.
Такая проблема: вызов вида
$preparedQuery->paginate($count)->appends($options)
возвращает объект, не являющийся итератором (Invalid argument supplied for foreach()
). Laravel версии 5.5.2. Как мне получить результат построчно в этом случае?Пагинация Массива Ларавелем. 5.5
https://laravel.ru/forum/viewtopic.php?id=3118
Приветствую всех, сделал пагинатор и всё выводит но стили бутстрап именно в этой части
{!! $posts->links(); !!}
не работают. Все стили бутстрап подключены и работаю согласно инструкции бутстрап.Это во view?
Если да, то должно быть так:
{{ $posts->links() }}
Если поместить это в div? Что именно уже проделано?
Я всяко пробовал и в диве, только толку никакого.
Здравствуйте.
Раньше пагинация работала, а сейчас произошла такая проблема, что когда ты нажимаешь на след страницу у меня просто добавляется category?page=2 и ничего не меняется