分頁(yè)
分頁(yè)
數(shù)據(jù)庫(kù): 分頁(yè)
簡(jiǎn)介
在其它框架中,分頁(yè)可能非常痛苦。Laravel 的分頁(yè)器將 查詢(xún)構(gòu)造器 和 Eloquent ORM 結(jié)合起來(lái),提供了方便、易用的數(shù)據(jù)庫(kù)結(jié)果集分頁(yè)。通過(guò)分頁(yè)器生成的 HTML 兼容 Bootstrap CSS 框架。
基本用法
查詢(xún)構(gòu)造器分頁(yè)
數(shù)據(jù)分頁(yè)有幾種方法。最簡(jiǎn)單的是使用 查詢(xún)構(gòu)造器 或 Eloquent query 的 paginate
方法。paginate
方法根據(jù)用戶(hù)瀏覽的當(dāng)前頁(yè)碼,自動(dòng)設(shè)置恰當(dāng)?shù)钠屏?offset 和限制數(shù) limit。默認(rèn)情況下,HTTP 請(qǐng)求中的 page
查詢(xún)參數(shù)值被當(dāng)作當(dāng)前頁(yè)的頁(yè)碼。Lavarel 自動(dòng)偵測(cè)該值,并自動(dòng)將其插入到分頁(yè)器生成的鏈接中。
在下面的例子中,傳遞給 paginate
方法的唯一參數(shù)是你希望在每頁(yè)顯示的記錄條數(shù)。在此處,我們指定要在每頁(yè)顯示 15
條數(shù)據(jù):
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; use App\Http\Controllers\Controller; class UserController extends Controller{ /** * 顯示應(yīng)用程序中的所有用戶(hù)。 * * @return Response */ public function index() { $users = DB::table('users')->paginate(15); return view('user.index', ['users' => $users]); } }
{note} 目前,Lavarel 無(wú)法高效地執(zhí)行使用了
groupBy
語(yǔ)句的分頁(yè)操作。如果你需要使用對(duì)使用了groupBy
的結(jié)果集分頁(yè),建議你手工查詢(xún)數(shù)據(jù)庫(kù)并創(chuàng)建分頁(yè)。
簡(jiǎn)單分頁(yè)
如果只需要在你的分頁(yè)視圖中簡(jiǎn)單地顯示『下一頁(yè)』和『上一頁(yè)』鏈接,你可以使用 simplePaginate
方法執(zhí)行更高效地查詢(xún)。這在數(shù)據(jù)很多且不需要在渲染視圖時(shí)顯示每頁(yè)的頁(yè)碼時(shí)非常有用:
$users = DB::table('users')->simplePaginate(15);
Eloquent 分頁(yè)
你還能對(duì) Eloquent 查詢(xún)結(jié)果分頁(yè)。在下面的例子中,我們將對(duì) User
模型按每頁(yè) 15
條分頁(yè)。如你所見(jiàn),其語(yǔ)法與查詢(xún)構(gòu)造器分頁(yè)基本雷同:
$users = App\User::paginate(15);
你還可以在調(diào)用 paginate
之前,在查詢(xún)中設(shè)置諸如 where
從句的其它約束:
$users = User::where('votes', '>', 100)->paginate(15);
在 Eloquent 分頁(yè)中還能使用 simplePaginate
方法:
$users = User::where('votes', '>', 100)->simplePaginate(15);
手動(dòng)創(chuàng)建分頁(yè)
有時(shí)你可能希望手動(dòng)創(chuàng)建分頁(yè),并傳遞一個(gè)數(shù)組集給它??梢酝ㄟ^(guò)創(chuàng)建 Illuminate\Pagination\Paginator
或 Illuminate\Pagination\LengthAwarePaginator
實(shí)例來(lái)實(shí)現(xiàn),這有賴(lài)于你的需要。.
Paginator
類(lèi)不需要知道結(jié)果集的總數(shù);但是,這樣一來(lái),這個(gè)類(lèi)就沒(méi)辦法獲知最后一頁(yè)的索引。 LengthAwarePaginator
接受和 Paginator
幾乎相同的參數(shù);不過(guò),它會(huì)計(jì)算結(jié)果集的總數(shù)。
換句話說(shuō), Paginator
相當(dāng)于 查詢(xún)構(gòu)造器 或 Eloquent 的 simplePaginate
方法,而 LengthAwarePaginator
相當(dāng)于 paginate
方法。
{note} 在手動(dòng)創(chuàng)建分頁(yè)實(shí)例時(shí),需要人為 “切割” 傳遞給分頁(yè)實(shí)例的結(jié)果數(shù)組。如果你對(duì)此沒(méi)有把握,請(qǐng)參考 PHP 的 array_slice 函數(shù)。
顯示結(jié)果集
調(diào)用 paginate
方法時(shí),會(huì)得到 Illuminate\Pagination\LengthAwarePaginator
實(shí)例。調(diào)用 simplePaginate
方法,得到的是 Illuminate\Pagination\Paginator
實(shí)例。這些對(duì)象提供了分析結(jié)果集的幾個(gè)方法。 除了這些輔助方法,分頁(yè)器實(shí)例合為迭代器,可以像數(shù)組一樣循環(huán)。因此,當(dāng)?shù)玫浇Y(jié)果后,可以使用 Blade 顯示數(shù)據(jù)、渲染分頁(yè)鏈接:
<div class="container"> @foreach ($users as $user) {{ $user->name }} @endforeach </div> {{ $users->links() }}
links
方法渲染結(jié)果集中剩余頁(yè)面的鏈接。每個(gè)鏈接都包含 page
URL 變量。記住, links
生成的 HTML 兼容 Bootstrap CSS 框架。
自定義分頁(yè)器 URI
withPath
方法允許你在生成分頁(yè)鏈接時(shí)自定義 URI 。例如,如果你想生成形如 http://example.com/custom/url?page=N
的分頁(yè)鏈接,只需要傳遞 custom/url
參數(shù)給 withPath
方法:
Route::get('users', function () { $users = App\User::paginate(15); $users->withPath('custom/url'); // });
附加參數(shù)到分頁(yè)鏈接
可以使用 appends
方法,向分頁(yè)鏈接中添加查詢(xún)參數(shù)。例如,要在每頁(yè)鏈接中添加 sort=votes
,只需要這樣調(diào)用 appends
:
{{ $users->appends(['sort' => 'votes'])->links() }}
如果想要向分頁(yè)器 URL 添加 “哈希片段”,可以使用 fragment
方法。例如,要在每頁(yè)鏈接中添加 #foo
,只要這樣調(diào)用 fragment
方法:
{{ $users->fragment('foo')->links() }}
調(diào)整分頁(yè)鏈接窗口
你能夠控制在分頁(yè)器的 “窗口” 的每一側(cè)顯示多少個(gè)附加鏈接。默認(rèn)情況下,主分頁(yè)鏈接的每側(cè)顯示三個(gè)鏈接??梢允褂?onEachSide
方法改變這個(gè)數(shù)值:
{{ $users->onEachSide(5)->links() }}
將結(jié)果轉(zhuǎn)換為 JSON
Laravel 分頁(yè)器類(lèi)實(shí)現(xiàn)了 Illuminate\Contracts\Support\Jsonable
接口契約,提供了 toJson
方法,能夠方便地將分頁(yè)結(jié)果轉(zhuǎn)換為 JSON 。還可以通過(guò)自路由或控制器操作返回分頁(yè)器實(shí)例來(lái)將其轉(zhuǎn)換為 JSON :
Route::get('users', function () { return App\User::paginate(); });
來(lái)自分頁(yè)器的 JSON 將包括諸如 total
, current_page
, last_page
等元數(shù)據(jù)信息。實(shí)際結(jié)果對(duì)象將通過(guò) JSON 數(shù)組的 data
鍵提供。以下是通過(guò)自路由中返回分頁(yè)器實(shí)例的方式創(chuàng)建 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":[ { // 結(jié)果集對(duì)象 }, { // 結(jié)果集對(duì)象 } ] }
自定義分頁(yè)視圖
默認(rèn)情況下,渲染視圖以顯示分頁(yè)鏈接與 Bootstrap CSS 框架兼容。如果你不使用 Bootstrap,可以隨心所欲地定制自己的視圖來(lái)渲染這些鏈接。在調(diào)用分頁(yè)器實(shí)例的 links
方法時(shí),將視圖名稱(chēng)作為傳遞給它的第一個(gè)參數(shù):
{{ $paginator->links('view.name') }} // Passing data to the view... {{ $paginator->links('view.name', ['foo' => 'bar']) }}
自定義分頁(yè)視圖的最簡(jiǎn)方法是使用 vendor:publish
命令將它們輸出到 resources/views/vendor
文件夾:
php artisan vendor:publish --tag=laravel-pagination
此命令將在 resources/views/vendor/pagination
文件夾放置這些視圖。內(nèi)置在該文件夾下的 bootstrap-4.blade.php
文件提供了默認(rèn)的分頁(yè)視圖??梢跃庉嫶宋募孕薷姆猪?yè) HTML。
如果想要定義不同的文件作為默認(rèn)分頁(yè)視圖,需要在 AppServiceProvider
中使用分頁(yè)器的 defaultView
和 defaultSimpleView
方法:
use Illuminate\Pagination\Paginator;public function boot(){ Paginator::defaultView('view-name'); Paginator::defaultSimpleView('view-name'); }
分頁(yè)器實(shí)例方法
每個(gè)分頁(yè)器實(shí)例提供了如下方法獲取附加的分頁(yè)信息::
方法 | 描述 |
---|---|
$results->count() | 獲取當(dāng)前頁(yè)數(shù)據(jù)數(shù)量。 |
$results->currentPage() | 獲取當(dāng)前頁(yè)頁(yè)碼。 |
$results->firstItem() | 獲取結(jié)果集中第一條數(shù)據(jù)的結(jié)果編號(hào)。 |
$results->getOptions() | 獲取分頁(yè)器選項(xiàng)。 |
$results->getUrlRange($start, $end) | 創(chuàng)建分頁(yè) URL 范圍。 |
$results->hasMorePages() | 是否有多頁(yè)。 |
$results->lastItem() | 獲取結(jié)果集中最后一條數(shù)據(jù)的結(jié)果編號(hào)。 |
$results->lastPage() | 獲取最后一頁(yè)的頁(yè)碼(在 simplePaginate 中無(wú)效)。 |
$results->nextPageUrl() | 獲取下一頁(yè)的 URL 。 |
$results->onFirstPage() | 當(dāng)前而是否為第一頁(yè)。 |
$results->perPage() | 每頁(yè)的數(shù)據(jù)條數(shù)。 |
$results->previousPageUrl() | 獲取前一頁(yè)的 URL。 |
$results->total() | 數(shù)據(jù)總數(shù)(在 simplePaginate 無(wú)效)。 |
$results->url($page) | 獲取指定頁(yè)的 URL。 |