# 服務 —— 分頁
## 1、簡介
在其他框架中,分頁是件非常痛苦的事,Laravel則使其變得輕而易舉。Laravel能夠基于當前頁智能生成一定范圍的鏈接,且生成的HTML兼容[Bootstrap CSS 框架](http://getbootstrap.com/)。
## 2、基本使用
### 2.1 基于查詢構建器分頁
有多種方式實現分頁,最簡單的方式就是使用[查詢構建器](http://laravelacademy.org/post/126.html)或Eloquent模型的`paginate`方法。該方法基于當前用戶查看頁自動設置合適的偏移(offset)和限制(limit)。默認情況下,當前頁通過HTTP請求查詢字符串參數`?page`的值判斷。當然,該值由Laravel自動檢測,然后自動插入分頁器生成的鏈接中。
讓我們先來看看如何在查詢上調用`paginate`方法。在本例中,傳遞給`paginate`的唯一參數就是你每頁想要顯示的數目,這里我們指定每頁顯示`15`個:
~~~
<?php
namespace App\Http\Controllers;
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]);
}
}
~~~
> 注意:目前,使用`groupBy`的分頁操作不能被Laravel有效執行,如果你需要在分頁結果中使用`groupBy`,推薦你手動查詢數據庫然后創建分頁器。
### 2.1.1 “簡單分頁”
如果你只需要在分頁視圖中簡單的顯示“下一個”和“上一個”鏈接,可以使用`simplePaginate`方法來執行該查詢。在渲染包含大數據集的視圖且不需要顯示每個頁碼時非常有用:
~~~
$users = DB::table('users')->simplePaginate(15);
~~~
### 2.2 基于Eloquent模型分頁
你還可以對[Eloquent](http://laravelacademy.org/post/138.html)查詢結果進行分頁,在本例中,我們對`User`模型進行分頁,每頁顯示`15`條記錄。正如你所看到的,該語法和基于查詢構建器的分頁差不多:
~~~
$users = App\User::paginate(15);
~~~
當然,你可以在設置其它約束調價之后調用`paginate`,比如`where`子句:
~~~
$users = User::where('votes', '>', 100)->paginate(15);
~~~
你也可以使用`simplePaginate`方法:
~~~
$users = User::where('votes', '>', 100)->simplePaginate(15);
~~~
### 2.3 手動創建分頁器
有時候你可能想要通過傳遞數組數據來手動創建分頁實例,你可以基于自己的需求通過創建`Illuminate\Pagination\Paginator`或`Illuminate\Pagination\LengthAwarePaginator`實例來實現。
`Paginator`類不需要知道結果集中數據項的總數;然而,正因如此,該類也沒有提供獲取最后一頁索引的方法。
`LengthAwarePaginator`接收參數和`Paginator`幾乎一樣,只是,它要求傳入結果集的總數。
換句話說,`Paginator`?對應`simplePaginate`方法,而`LengthAwarePaginator`對應`paginate`方法。
當手動創建分頁器實例的時候,應該手動對傳遞到分頁器的結果集進行“切片”,如果你不確定怎么做,查看PHP函數[array_slice](http://php.net/manual/en/function.array-slice.php)。
## 3、在視圖中顯示分頁結果
當你調用查詢構建器或Eloquent查詢上的`paginate`或`simplePaginate`方法時,你將會獲取一個分頁器實例。當調用`paginate`方法時,你將獲取`Illuminate\Pagination\LengthAwarePaginator`,而調用方法`simplePaginate`時,將會獲取`Illuminate\Pagination\Paginator`實例。這些對象提供相關方法描述這些結果集,除了這些幫助函數外,分頁器實例本身就是迭代器,可以像數組一樣對其進行循環調用。
所以,獲取到結果后,可以按如下方式使用[Blade](http://laravelacademy.org/post/79.html)顯示這些結果并渲染頁面鏈接:
~~~
<div class="container">
@foreach ($users as $user)
{{ $user->name }}
@endforeach
</div>
{!! $users->render() !!}
~~~
`render`方法將會將結果集中的其它頁面鏈接渲染出來。每個鏈接已經包含了`?page`查詢字符串變量。記住,`render`方法生成的HTML兼容[Bootstrap CSS 框架](https://getbootstrap.com/)。
> 注意:我們從Blade模板調用`render`方法時,確保使用`{!!?!!}`語法以便HTML鏈接不被過濾。
### 3.1 自定義分頁器URI
`setPath`方法允許你生成分頁鏈接時自定義分頁器使用的URI,例如,如果你想要分頁器生成形如`http://example.com/custom/url?page=N`的鏈接,應該傳遞`custom/url`到`setPath`方法:
~~~
Route::get('users', function () {
$users = App\User::paginate(15);
$users->setPath('custom/url');
//
});
~~~
### 3.2 添加參數到分頁鏈接
你可以使用`appends`方法添加查詢參數到分頁鏈接查詢字符串。例如,要添加`&sort=votes`到每個分頁鏈接,應該像如下方式調用`appends`:
~~~
{!! $users->appends(['sort' => 'votes'])->render() !!}
~~~
如果你想要添加”哈希片段”到分頁鏈接,可以使用`fragment`方法。例如,要添加`#foo`到每個分頁鏈接的末尾,像這樣調用`fragment`方法:
~~~
{!! $users->fragment('foo')->render() !!}
~~~
### 3.3 更多幫助方法
你還可以通過如下分頁器實例上的方法訪問更多分頁信息:
* `$results->count()`
* `$results->currentPage()`
* `$results->hasMorePages()`
* `$results->lastPage() (使用simplePaginate時無效)`
* `$results->nextPageUrl()`
* `$results->perPage()`
* `$results->total() (使用simplePaginate時無效)`
* `$results->url($page)`
## 4、將結果轉化為JSON
Laravel分頁器結果類實現了`Illuminate\Contracts\Support\JsonableInterface`[契約](http://laravelacademy.org/post/95.html)并實現`toJson`方法,所以將分頁結果轉化為JSON非常簡單。
你還可以簡單通過從路由或控制器動作返回分頁器實例將轉其化為JSON:
~~~
Route::get('users', function () {
return App\User::paginate();
});
~~~
從分頁器轉化來的JSON包含了元信息如`total`,?`current_page`,`last_page`等等,實際的結果對象數據可以通過該JSON數組中的`data`鍵訪問。下面是一個通過從路由返回的分頁器實例創建的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":[
{
// Result Object
},
{
// Result Object
}
]
}
~~~
- 前言
- 序言
- 序言 ―― 發行版本說明
- 序言 ―― 升級指南
- 序言 ―― 貢獻代碼
- 開始
- 開始 ―― 安裝及配置
- 開始 ―― Laravel Homestead
- 基礎
- 基礎 ―― HTTP路由
- 基礎 ―― HTTP 中間件
- 基礎 ―― HTTP 控制器
- 基礎 ―― HTTP 請求
- 基礎 ―― HTTP 響應
- 基礎 ―― 視圖
- 基礎 ―― Blade模板
- 架構
- 架構 ―― 一次請求的生命周期
- 架構 ―― 應用目錄結構
- 架構 ―― 服務提供者
- 架構 ―― 服務容器
- 架構 ―― 契約
- 架構 ―― 門面
- 數據庫
- 數據庫 ―― 起步
- 數據庫 ―― 查詢構建器
- 數據庫 ―― 遷移
- 數據庫 ―― 填充數據
- Eloquent ORM
- Eloquent ORM ―― 起步
- Eloquent ORM ―― 關聯關系
- Eloquent ORM ―― 集合
- Eloquent ORM ―― 調整器
- Eloquent ORM ―― 序列化
- 服務
- 服務 ―― 用戶認證
- 服務 ―― Artisan 控制臺
- 服務 ―― Laravel Cashier(交易)
- 服務 ―― 緩存
- 服務 ―― 集合
- 服務 ―― Laravel Elixir
- 服務 ―― 加密
- 服務 ―― 錯誤&日志
- 服務 ―― 事件
- 服務 ―― 文件系統/云存儲
- 服務 ―― 哈希
- 服務 ―― 幫助函數
- 服務 ―― 本地化
- 服務 ―― 郵件
- 服務 ―― 包開發
- 服務 ―― 分頁
- 服務 ―― 隊列
- 服務 ―― Redis
- 服務 ―― Session
- 服務 ―― Envoy 任務運行器(SSH任務)
- 服務 ―― 任務調度
- 服務 ―― 測試
- 服務 ―― 驗證