分頁類?
CodeIgniter 提供了一個非常簡單但靈活的分頁庫,該庫主題簡單,可以在 Model 中使用,并能夠在單個頁面上支持多個分頁器。
加載庫?
與 CodeIgniter 中的所有服務一樣,它可以通過 Config\Services
進行加載,盡管通常它并不需要手動加載:
$pager = \Config\Services::pager();
分頁數據庫結果?
通常,可以使用分頁器庫對從數據庫中檢索到的結果進行分頁。使用 Model 類時,可以使用其內置的 paginate()
方法來自動檢索當前批次的結果,并設置 Pager 庫,以便可以在控制器中使用它。它甚至可以通過 page=X
變量從當前 URL 讀取當前應顯示的頁面。
在你的應用程序中提供用戶的分頁列表時,控制器的方法應類似于:
<?php namespace App\Controllers;
use CodeIgniter\Controller;
class UserController extends Controller
{
public function index()
{
$model = new \App\Models\UserModel();
$data = [
'users' => $model->paginate(10),
'pager' => $model->pager
];
echo view('users/index', $data);
}
}
在上面的示例中,我們首先創建了 UserModel 的實例。然后,我們對它填充數據來發送到視圖。第一個元素是來自數據庫 users 的結果, 這將針對正確的頁面進行檢索,每頁會返回 10 個用戶。發送到視圖的第二個必須的項是 Pager 實例本身。為了方便起見,Model 將會保留所使用的實例, 并將其存儲在 public 類變量 $pager 中。因此,我們將其獲取并將其分配給視圖中的 $pager 變量。
然后,在視圖內,我們需要告訴它應該在哪里顯示結果的鏈接:
<?= $pager->links() ?>
就是這樣。Pager 類將為當前頁面兩側超過兩個頁面的任何頁面呈現“首頁”和“末頁”的鏈接,以及“下一頁”和“上一頁”的鏈接。
如果你更喜歡簡單的輸出,則可以使用 simpleLinks()
方法,它會輸出“較舊”和“較新”鏈接而不是有著詳細信息的分頁鏈接:
<?= $pager->simpleLinks() ?>
在后臺中,庫加載了一個視圖文件,文件確定鏈接的格式,從而可以輕松地根據需要進行修改。有關如何完全自定義輸出的詳細信息,請參見下文。
分頁多個結果?
如果需要提供來自兩個不同的結果集的鏈接,則可以將組名傳遞給大多數分頁方法,以使數據分開:
// 在控制器文件中:
public function index()
{
$userModel = new \App\Models\UserModel();
$pageModel = new \App\Models\PageModel();
$data = [
'users' => $userModel->paginate(10, 'group1'),
'pages' => $pageModel->paginate(15, 'group2'),
'pager' => $userModel->pager
];
echo view('users/index', $data);
}
// 在視圖文件中:
<?= $pager->links('group1') ?>
<?= $pager->simpleLinks('group2') ?>
手動分頁?
你可能會發現有時候只需要根據已知數據來創建分頁。這時你可以使用 makeLinks()
方法來手動創建鏈接,這個方法分別將當前頁面,
每頁的結果數和項目總數作為第一個,第二個和第三個參數:
<?= $pager->makeLinks($page, $perPage, $total) ?>
默認情況下,這將以正常方式將鏈接顯示為一組鏈接,你還可以通過將模板名稱作為第四個參數傳入來更改使用的顯示模板。在以下各節中可以找到更多詳細信息。
<?= $pager->makeLinks($page, $perPage, $total, 'template_name') ?>
也可以使用 URI 字段(segment)而不是用查詢參數來表示頁碼,只需指定字段號即可用作的第五個參數 makeLinks()
。然后,由分頁器生成的 URI 看起來會像
https://domain.tld/model/『頁碼』 而不是 https://domain.tld/model?page=『頁碼』 。
<?= $pager->makeLinks($page, $perPage, $total, 'template_name', $segment) ?>
請注意: $segment
的值不能大于 URI 字段的數量加 1。
如果你需要在一頁上顯示很多分頁器,那么定義組的其他參數可能會有所幫助:
$pager = service('pager');
$pager->setPath('path/for/my-group', 'my-group'); // 另外,你可以為每個組定義路徑
$pager->makeLinks($page, $perPage, $total, 'template_name', $segment, 'my-group');
僅使用預期查詢進行分頁?
默認情況下,所有 GET 查詢都顯示在分頁鏈接中。
例如,當訪問 URL http://domain.tld?search=foo&order=asc&hello=i+am+here&page=2 時,可以生成 頁面 3 鏈接以及其他鏈接,如下所示:
echo $pager->links();
// 頁面 3 鏈接: http://domain.tld?search=foo&order=asc&hello=i+am+here&page=3
only()
方法還允許你將其限制為僅已預期的查詢:
echo $pager->only(['search', 'order'])->links();
// 頁面 3 鏈接: http://domain.tld?search=foo&order=asc&page=3
page 查詢默認情況下啟用。并 only()
在所有分頁鏈接中起作用。
自定義鏈接?
查看配置?
當鏈接呈現到頁面時,它們使用視圖文件來渲染 HTML。你可以通過編輯 app/Config/Pager.php 來輕松地更改使用的視圖:
public $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple'
];
設置存儲應使用的視圖的別名和 命名空間的視圖路徑 。 default_full 和 default_simple
視圖會分別被用于 links()
和 simpleLinks()
方法。要更改在整個應用程序范圍內顯示的方式,你可以在處分配一個新視圖。
例如,假設你創建一個與 Foundation CSS 框架一起使用的新視圖文件,然后將文件放在 app/Views/Pagers/foundation_full.php 中。
由于 application 目錄的命名空間為 App
,并且其下的所有目錄都直接映射到命名空間的各個部分,因此你可以通過其命名空間找到視圖文件:
'default_full' => 'App\Views\Pagers\foundation_full',
但是,由于它位于標準的 app/Views 目錄下,因此不需要命名空間,因為``view()`` 方法可以按文件名定位它。在這種情況下,你只需提供子目錄和文件名:
'default_full' => 'Pagers/foundation_full',
創建視圖并將其配置好后,將會自動使用它。你不必替換現有模板。你也可以在配置文件中根據需要創建的任意數量的其他模板。常見的情況是你的應用程序的前端和后端需要不同的樣式。
public $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
'front_full' => 'App\Views\Pagers\foundation_full',
];
配置完成后,你可以指定它作為 links()
、 simpleLinks()
以及 makeLinks()
方法的最后的一個參數:
<?= $pager->links('group1', 'front_full') ?>
<?= $pager->simpleLinks('group2', 'front_full') ?>
<?= $pager->makeLinks($page, $perPage, $total, 'front_full') ?>
創建視圖?
創建新視圖時,只需要創建生成分頁鏈接本身所需的代碼。你不應該創建不必要的包裝 div,因為它可能會在多個地方使用,并且這會限制它們的用途。這里通過向你展示現有的 default_full 模板,來演示創建新視圖:
<?php $pager->setSurroundCount(2) ?>
<nav aria-label="Page navigation">
<ul class="pagination">
<?php if ($pager->hasPrevious()) : ?>
<li>
<a href="<?= $pager->getFirst() ?>" aria-label="First">
<span aria-hidden="true">First</span>
</a>
</li>
<li>
<a href="<?= $pager->getPrevious() ?>" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<?php endif ?>
<?php foreach ($pager->links() as $link) : ?>
<li <?= $link['active'] ? 'class="active"' : '' ?>>
<a href="<?= $link['uri'] ?>">
<?= $link['title'] ?>
</a>
</li>
<?php endforeach ?>
<?php if ($pager->hasNext()) : ?>
<li>
<a href="<?= $pager->getNext() ?>" aria-label="Previous">
<span aria-hidden="true">»</span>
</a>
</li>
<li>
<a href="<?= $pager->getLast() ?>" aria-label="Last">
<span aria-hidden="true">Last</span>
</a>
</li>
<?php endif ?>
</ul>
</nav>
setSurroundCount()
在第一行中,setSurroundCount()
方法指定了我們要顯示到當前頁面鏈接兩側的兩個鏈接。它接受的唯一參數是要顯示的鏈接數。
hasPrevious() & hasNext()
如果根據傳遞給 setSurroundCount
的值,如果當前頁面的任何一側上可以顯示更多鏈接,則這些方法將返回布爾值 true。例如,假設我們有 20 頁數據,當前頁面是第 3 頁,如果周圍的計數是 2,則以下鏈接將顯示在列表中:1、2、3、4 和 5。由于要顯示的第一個鏈接是第 1 頁,但是頁面 0 并不存在,因此 hasPrevious()
會返回 false 。但是, hasNext()
將返回 true ,因為在第 5 頁之后還有 15 個額外的結果頁。
getPrevious() & getNext()
這兩個方法返回編號鏈接兩側上一頁或下一頁結果的 URL。有關完整說明,請參見上一段。
getFirst() & getLast()
與 getPrevious()
和 getNext()
類似,這兩個方法返回指向結果集中第一頁和最后一頁的鏈接。
links()
返回所有有關編號鏈接的數據數組。每個鏈接的數組都包含鏈接的 uri,標題(只是數字)和一個布爾值,布爾值表示鏈接為當前鏈接還是活動鏈接:
$link = [
'active' => false,
'uri' => 'http://example.com/foo?page=2',
'title' => 1
];