什麼是 PEAR Pager?
PEAR::Pager 是 PHP 經典的分頁處理套件,支援多種分頁模式 (Jumping, Sliding)、自定義連結樣式、資料來源抽象 (陣列、資料庫、XML 等)、SEO 友善 URL。雖屬較舊專案,但邏輯清晰,適合理解分頁核心概念或維護舊系統。
安裝方式
# PEAR 安裝器 (傳統)
pear install Pager
# Composer (現代專案整合)
composer require pear/pager
最小可運行範例 (官方示例簡化)
<?php
require_once 'Pager.php';
// 1. 準備資料來源 (這裡用陣列模擬 180 筆資料)
$params['itemData'] = range(1, 180);
// 2. 實例化 Pager (預設 Jumping 模式,每頁 10 筆)
$pager =& new Pager($params);
// 3. 取得當前頁資料
$data = $pager->getPageData();
// 4. 產生分頁導航連結
$links = $pager->getLinks('<<上頁', '下頁>>');
// 5. 取得當前頁資料範圍 (用於顯示「第 X-Y 筆,共 Z 筆」)
list($from, $to) = $pager->getOffsetByPageId();
?>
<html>
<body>
<table border="0" width="100%">
<tr>
<td colspan="3" align="center">
顯示 [<?=$from?> - <?=$to?>] 條記錄,共<?=$pager->_totalItems?>條記錄 <br />
<?=$links['pages']?>
</td>
</tr>
<tr>
<td><nobr><?=$links['back']?></nobr></td>
<td align="center" width="100%"> </td>
<td align="right"><nobr><?=$links['next']?></nobr></td>
</tr>
<tr>
<td colspan="3">
<pre><?=print_r($data, true)?></pre>
</td>
</tr>
</table>
</body>
</html>
核心參數配置詳解
| 參數 | 預設值 | 說明 |
itemData | 無 | **資料來源**:陣列、資料庫結果集、XML 物件等 (實作 Pager_Interface 可擴展) |
perPage | 10 | 每頁筆數 |
mode | 'Jumping' | 分頁模式:'Jumping' (固定頁塊) / 'Sliding' (當前頁居中) |
delta | 10 | 顯示頁碼數量 (Jumping: 頁塊大小 / Sliding: 前後各幾頁) |
httpMethod | 'GET' | 連結方法 |
varPage | 'pageID' | URL 參數名 (如 ?pageID=3) |
path | 當前腳本 | 連結基礎路徑 |
fileName | 當前檔名 | 連結檔名 (配合 path) |
append | '' | 額外查詢字串 (如 &sort=desc) |
altPrev | '<' | 上一頁連結 title/alt 文字 |
altNext | '>' | 下一頁連結 title/alt 文字 |
separator | ' ' | 頁碼分隔符 |
clearIfVoid | true | 單頁時隱藏導航 |
進階用法:資料庫分頁 (PDO 整合)
<?php
require_once 'Pager.php';
require_once 'Pager/Wrapper.php'; // 資料庫包裝器
// PDO 連線
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
// 總筆數查詢 (Pager 需要)
$total = $pdo->query("SELECT COUNT(*) FROM articles WHERE status=1")->fetchColumn();
// 實例化 (使用 Wrapper 自動處理 LIMIT/OFFSET)
$params = [
'perPage' => 20,
'mode' => 'Sliding',
'delta' => 5,
'append' => '&cat=tech',
];
$pager =& new Pager_Wrapper($pdo, $params);
// 取得當前頁資料 (自動執行 SELECT ... LIMIT offset, perPage)
$data = $pager->getPageData(
"SELECT id, title, created_at FROM articles WHERE status=1 ORDER BY created_at DESC"
);
// 導航連結
$links = $pager->getLinks('« 上一頁', '下一頁 »');
// 模板輸出
foreach ($data as $row) {
echo "<div><a href='/article/{$row['id']}'>{$row['title']}</a> <small>{$row['created_at']}</small></div>";
}
echo $links['all']; // 完整導航 HTML
兩大分頁模式視覺化差異
| 模式 | 行為 | 適用場景 |
| Jumping | 頁碼分塊 (1-10, 11-20...),當前頁在塊內跳動,換塊時頁碼整組跳躍 | 傳統後台、資料量固定、SEO 需固定 URL 結構 |
| Sliding | 當前頁**永居中間**,前後各顯示 delta 頁 (如 3 4 [5] 6 7),極邊界自動調整 | 現代前端、用戶體驗優先、長列表瀏覽 |
常見問題與避坑
| 問題 | 原因 | 解決 |
| 分頁連結指向錯誤 URL | path/fileName/varPage 未正確設定 | 明確指定 'path' => '/admin/users/', 'fileName' => 'index.php', 'varPage' => 'p' |
| 資料庫 Wrapper 報錯 | SQL 含 LIMIT / 參數綁定衝突 | 傳入 **不含 LIMIT** 的基礎查詢,Wrapper 自動注入 |
| 大資料集效能差 | COUNT(*) 全表掃描 | 使用觸發器維護計數表 / 估算值 / 延遲載入 |
| 中文參數亂碼 | URL 編碼不一致 | 統一 UTF-8,urlencode() 參數值,append 已編碼 |
現代替代方案對照
| 方案 | 特點 | 學習曲線 |
| Laravel Paginator | 內建 Eloquent/Query Builder 整合、Bootstrap/Tailwind 視圖、JSON API 支援 | 低 (框架內建) |
| Symfony Pagerfanta | 介面導向、多適配器 (Doctrine, Array, Propel)、Twig 擴充 | 中 |
| knp-components/Pager | Zend/純 PHP 專案、Sliding/Jumping、可擴展模板 | 中 |
| 自寫簡易分頁 | LIMIT (page-1)*size, size + 總數查詢,< 50 行代碼 | 極低 |
總結
- PEAR Pager 以
itemData 抽象資料來源,getPageData() 取資料,getLinks() 產導航,核心極簡
- 關鍵參數:
mode (Jumping/Sliding)、perPage、delta、varPage
- 資料庫分頁需配合
Pager_Wrapper,傳入**不含 LIMIT 的基礎查詢**
- 現代專案優先框架內建分頁,但理解 Pager 的 **資料來源抽象、模式差異、連結生成邏輯** 有助於設計自訂分頁組件