1. 程式人生 > >laravel自帶分頁類的使用

laravel自帶分頁類的使用

簡介

在其他框架中,分頁是件非常痛苦的事,Laravel 讓這件事變得簡單易於上手。Laravel 的分頁器與查詢構建器和 Eloquent ORM 整合在一起,並開箱提供方便的、易於使用的、基於資料庫結果集的分頁。分頁器生成的 HTML 相容 Bootstrap CSS 框架。

基本使用

基於查詢構建器進行分頁

有多種方式實現分頁功能,最簡單的方式就是使用查詢構建器或 Eloquent 查詢提供的 paginate 方法。該方法基於當前使用者檢視頁自動設定合適的偏移(offset)和限制(limit),直白點說就是頁碼和每頁顯示數量。預設情況下,當前頁通過 HTTP 請求查詢字串引數 page

 的值判斷。當然,該值由 Laravel 自動檢測,然後自動插入分頁器生成的連結中。

讓我們先來看看如何在查詢中呼叫 paginate 方法。在本例中,傳遞給 paginate 的唯一引數就是你每頁想要顯示的數目,這裡我們指定每頁顯示 15 個:

<?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]);
    }
}

注:目前,使用 groupBy 的分頁操作不能被 Laravel 有效執行,如果你需要在分頁結果中使用 groupBy,推薦你手動查詢資料庫然後建立分頁器。

簡單分頁

如果你只需要在分頁檢視中簡單的顯示“下一頁”和“上一頁”連結,可以使用 simplePaginate 方法來執行一個更加高效的查詢。在渲染包含大資料集的檢視且不需要顯示每個頁碼時這一功能非常有用:

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

基於Eloquent結果集進行分頁

你還可以對 Eloquent 查詢結果進行分頁,在本例中,我們對 User

 模型進行分頁,每頁顯示 15 條記錄。正如你所看到的,該語法和基於查詢構建器的分頁差不多:

$users = App\User::paginate(15);

當然,你可以在設定其它約束條件之後呼叫 paginate,比如 where 子句:

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

在對 Eloquent 模型進行分頁時你也可以使用 simplePaginate 方法:

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

手動建立分頁器

有時候你可能想要通過傳遞陣列資料來手動建立分頁例項,你可以基於自己的需求通過建立 Illuminate\Pagination\Paginator 或 Illuminate\Pagination\LengthAwarePaginator 例項來實現。

Paginator 類不需要知道結果集中資料項的總數;不過,正因如此,該類也沒有提供獲取最後一頁索引的方法。LengthAwarePaginator 接收引數和 Paginator 幾乎一樣,唯一不同在於它要求傳入結果集的總數。

換句話說,Paginator 對應 simplePaginate 方法,而 LengthAwarePaginator 對應 paginate 方法。

注:當手動建立分頁器例項的時候,應該手動對傳遞到分頁器的結果集進行“切片”,如果你不確定怎麼做,檢視 PHP 函式 array_slice

顯示分頁結果

當呼叫 paginate 方法時,你將獲取Illuminate\Pagination\LengthAwarePaginator 例項,而呼叫方法simplePaginate 時,將會獲取 Illuminate\Pagination\Paginator 例項。這些物件提供相關方法描述這些結果集,除了這些輔助函式外,分頁器例項本身就是迭代器,可以像陣列一樣對其進行迴圈呼叫。所以,獲取到結果後,可以按如下方式使用 Blade 顯示這些結果並渲染頁面連結:

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

{{ $users->links() }}

links 方法將會將結果集中的其它頁面連結渲染出來。每個連結已經包含了 page 查詢字串變數。記住,render方法生成的 HTML 相容 Bootstrap CSS 框架。

自定義分頁連結

withPath 方法允許你生成分頁連結時自定義分頁器使用的 URI,例如,如果你想要分頁器生成形如 http://example.com/custom/url?page=N 的連結,應該傳遞 custom/url 到 withPath 方法:

Route::get('users', function () {
    $users = App\User::paginate(15);
    $users->withPath('custom/url');
    //
});

新增引數到分頁連結

你可以使用 appends 方法新增查詢引數到分頁連結查詢字串。例如,要新增 &sort=votes 到每個分頁連結,應該像如下方式呼叫 appends

{{ $users->appends(['sort' => 'votes'])->links() }}

如果你想要新增”雜湊片段”到分頁連結,可以使用 fragment 方法。例如,要新增 #foo 到每個分頁連結的末尾,像這樣呼叫 fragment 方法:

{{ $users->fragment('foo')->links() }}

將結果轉化為JSON

Laravel 分頁器結果類實現了 Illuminate\Contracts\Support\JsonableInterface 契約並提供了 toJson 方法,所以將分頁結果轉化為 JSON 非常簡單。你還可以通過從路由或控制器動作返回分頁器例項將轉其化為 JSON:

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

從分頁器轉化來的 JSON 包含了元資訊如 totalcurrent_pagelast_page 等等,實際的結果物件資料可以通過該 JSON 陣列中的 data 鍵訪問。下面是一個通過從路由返回的分頁器例項建立的 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":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

自定義分頁檢視

預設情況下,用於渲染分頁連結的檢視相容 Bootstrap CSS 框架,如果你沒有使用Bootstrap,可以自定義檢視來渲染這些連結。當呼叫分頁器例項上的 links 方法時,傳遞檢視名稱作為第一個引數:

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

// 傳遞資料到檢視...
{{ $paginator->links('view.name', ['foo' => 'bar']) }}

不過,自定義分頁檢視最簡單的方式是使用 vendor:publish 命令匯出檢視檔案到resources/views/vendor 目錄:

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

該命令會將檢視放到 resources/views/vendor/pagination 目錄,該目錄下的default.blade.php 檔案對應預設的檢視檔案,編輯該檔案即可修改分頁 HTML。

分頁器例項方法

每個分頁器例項都可以通過以下方法提供更多分頁資訊:

$results->count()
$results->currentPage()
$results->firstItem()
$results->hasMorePages()
$results->lastItem()
$results->lastPage() (使用simplePaginate 時無效)
$results->nextPageUrl()
$results->perPage()
$results->previousPageUrl()
$results->total() (使用simplePaginate 時無效)
$results->url($page)