設計目標
- 支援傳統靜態化 URL:
/list-p{page}.html
- 支援 AJAX 分頁:無連結時輸出
data-page 屬性供 JS 綁定
- 智能省略號:首尾頁、當前頁附近、間隔過大時顯示
...
- 多實例隔離:同頁多個分頁區塊通過
optype 標識區分
核心代碼(精簡重構版)
<?php
class Paginator {
/**
* 生成分頁 HTML
* @param string $baseUrl 基礎 URL,含 -p{page} 佔位符;空字符串表示 AJAX 模式
* @param int $current 當前頁碼 (>=1)
* @param int $total 總頁數
* @param int $window 當前頁兩側顯示頁數(默認 3,即共 7 個數字)
* @param string $type 多實例標識,用於 AJAX 區分
* @return string HTML 片段
*/
public static function render($baseUrl = '', $current, $total, $window = 3, $type = '') {
if ($total <= 1) return ''; // 單頁無需分頁
$html = '';
return $html;
}
}
// 用法示例
echo Paginator::render('/article/list-p{page}.html', 5, 20, 2, 'article');
// AJAX 模式
echo Paginator::render('', 1, 10, 3, 'comments');
AJAX 前端配合示例
<script>
// 通用加載函數,根據 optype 分發
function loadPage(el) {
const page = el.dataset.page;
const type = el.closest('.pagination').dataset.type || 'default';
// 發送 AJAX 請求,根據 type 更新對應容器
fetch(`/api/list?page=${page}&type=${type}`)
.then(r => r.json())
.then(data => {
document.getElementById(`list-${type}`).innerHTML = data.html;
// 重新渲染分頁
document.getElementById(`pager-${type}`).innerHTML = data.pager_html;
});
}
</script>
<!-- 容器 -->
<div id="list-comments">...</div>
<div id="pager-comments" class="pagination" data-type="comments"></div>
靜態化 URL 重寫規則
Nginx
location / {
rewrite ^/list-p(\d+)\.html$ /list.php?page=$1 last;
}
Apache (.htaccess)
RewriteRule ^list-p([0-9]+)\.html$ list.php?page=$1 [L]
擴展建議
- 加入
pageSize 參數,自動計算 $total = ceil($count / $pageSize)。
- 輸出
rel="prev/next"、aria-label 提升 SEO/無障礙。
- 整合框架:Laravel
LengthAwarePaginator、ThinkPHP \think\Paginator、Symfony KnpPaginatorBundle 已內建完善功能,優先使用框架組件。