paginate()當資料來源為第三方 API、快取陣列、手工組裝資料時,無法使用 Model/Builder 的 paginate()。需手動構建 LengthAwarePaginator 獲得相同分頁體驗。
Illuminate\Pagination\LengthAwarePaginatorpublic function __construct(
$items, // 當前頁資料 (Collection/Array)
$total, // 總筆數
$perPage, // 每頁筆數
$currentPage = null, // 當前頁碼
array $options = [] // path, pageName, fragment 等
) { ... }
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Http\Request;
public function userList(Request $request) {
// 模擬資料來源:陣列 7 筆
$users = [
['username' => 'zhangsan', 'age' => 26],
['username' => 'lisi', 'age' => 23],
['username' => 'wangwu', 'age' => 62],
['username' => 'zhaoliu', 'age' => 46],
['username' => 'wangmazi', 'age' => 25],
['username' => 'lanzi', 'age' => 24],
['username' => 'pangzi', 'age' => 21],
];
$perPage = 3; // 每頁 3 筆
// 1. 解析當前頁碼
$currentPage = $request->input('page', 1);
$currentPage = max(1, (int)$currentPage);
// 2. 手動切片取得當前頁資料(關鍵步驟!)
$offset = ($currentPage - 1) * $perPage;
$items = array_slice($users, $offset, $perPage);
// 3. 建立分頁器
$paginator = new LengthAwarePaginator(
$items,
count($users), // 總筆數
$perPage,
$currentPage,
[
'path' => Paginator::resolveCurrentPath(), // 當前 URL
'pageName' => 'page', // 參數名
]
);
// 4. 視圖變數
$userList = $paginator->toArray()['data']; // 當前頁資料陣列
return view('userlist', compact('userList', 'paginator'));
}
| 步驟 | 說明 | 常見錯誤 |
|---|---|---|
手動 array_slice | 必須自行切片,否則傳入完整陣列導致每頁顯示全部資料 | 忘記切片、offset 計算錯誤 |
total 參數 | 必須傳入總筆數,用於計算 lastPage | 傳入切片後筆數 |
path 設定 | 決定分頁連結基礎 URL,resolveCurrentPath() 自動獲取 | 連結指向錯誤頁面 |
回傳 Collection | 建議 collect($items),支援 toArray() 等方法 | 直接傳陣列雖可行但功能受限 |
{!! $paginator->links() !!} // Blade 5.3+ (舊版 render())
{!! $paginator->render() !!} // 相容舊版
// 自定義樣式
{!! $paginator->links('pagination::bootstrap-4') !!}
$paginator = new LengthAwarePaginator($items, $total, $perPage, $page, [
'path' => url('admin/users'),
'pageName' => 'p', // ?p=2
'fragment' => 'user-list', // #user-list
]);
// 或事後修改
$paginator->setPath('custom/url');
$paginator->setPageName('p');
$paginator->fragment('anchor');
Paginator若不需「最後一頁」連結,僅需「上一頁/下一頁」:
use Illuminate\Pagination\Paginator;
$paginator = new Paginator(
$items, $perPage, $currentPage,
['path' => Paginator::resolveCurrentPath()]
);
手動分頁三步曲:切片資料 → 計算總數 → 構建 LengthAwarePaginator。掌握此技巧,任何陣列資料源都能享受 Laravel 原生分頁體驗,包含連結生成、URL 參數管理、視圖輸出等完整功能。