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