分頁是列表頁面的標準配備。本文提供一個功能完整、零依賴的 SubPages 類別,支援「簡易模式」與「經典數字模式」兩種顯示風格,並可靈活配置每頁筆數、顯示頁碼數、連結前綴等參數。
<?php
class SubPages {
private $each_disNums; // 每頁顯示筆數
private $nums; // 總筆數
private $current_page; // 當前頁碼
private $sub_pages; // 顯示頁碼數量
private $pageNums; // 總頁數
private $page_array = []; // 待顯示頁碼陣列
private $subPage_link; // 分頁連結前綴 (如 "list.php?p=")
private $subPage_type; // 顯示類型 1=簡易 2=經典
public function __construct($each_disNums, $nums, $current_page, $sub_pages, $subPage_link, $subPage_type) {
$this->each_disNums = intval($each_disNums);
$this->nums = intval($nums);
$this->current_page = $current_page ? intval($current_page) : 1;
$this->sub_pages = intval($sub_pages);
$this->pageNums = ceil($this->nums / $this->each_disNums);
$this->subPage_link = $subPage_link;
$this->show_SubPages($subPage_type);
}
public function __destruct() {
// PHP 會自動回收屬性,此處僅示意
foreach ($this as $key => $val) { unset($this->$key); }
}
private function show_SubPages($type) {
if ($type == 1) $this->subPageCss1();
elseif ($type == 2) $this->subPageCss2();
}
private function initArray() {
for ($i = 0; $i < $this->sub_pages; $i++) $this->page_array[$i] = $i;
return $this->page_array;
}
// 核心演算法:計算要顯示的頁碼區間
private function construct_num_Page() {
if ($this->pageNums < $this->sub_pages) {
$current = [];
for ($i = 0; $i < $this->pageNums; $i++) $current[$i] = $i + 1;
} else {
$current = $this->initArray();
if ($this->current_page <= 3) {
// 頭部區間:1, 2, 3...
for ($i = 0; $i < count($current); $i++) $current[$i] = $i + 1;
} elseif ($this->current_page > $this->pageNums - $this->sub_pages + 1) {
// 尾部區間:... N-2, N-1, N
for ($i = 0; $i < count($current); $i++) $current[$i] = $this->pageNums - $this->sub_pages + 1 + $i;
} else {
// 中間區間:當前頁置中
for ($i = 0; $i < count($current); $i++) $current[$i] = $this->current_page - 2 + $i;
}
}
return $current;
}
// 模式 1:簡易模式 (無頁碼,只有首/上/下/尾)
private function subPageCss1() {
$str = "共 {$this->nums} 條記錄,每頁顯示 {$this->each_disNums} 條,當前第 {$this->current_page}/{$this->pageNums} 頁 ";
if ($this->current_page > 1) {
$str .= "[首頁] ";
$str .= "[上一頁] ";
} else {
$str .= "[首頁] [上一頁] ";
}
if ($this->current_page < $this->pageNums) {
$str .= "[下一頁] ";
$str .= "[尾頁] ";
} else {
$str .= "[下一頁] [尾頁] ";
}
echo $str;
}
// 模式 2:經典數字模式
private function subPageCss2() {
$str = "當前第 {$this->current_page}/{$this->pageNums} 頁 ";
if ($this->current_page > 1) {
$str .= "[首頁] ";
$str .= "[上一頁] ";
} else {
$str .= "[首頁] [上一頁] ";
}
$pages = $this->construct_num_Page();
foreach ($pages as $p) {
if ($p == $this->current_page) {
$str .= "[{$p}]";
} else {
$str .= "[{$p}]";
}
}
if ($this->current_page < $this->pageNums) {
$str .= " [下一頁] ";
$str .= "[尾頁] ";
} else {
$str .= "[下一頁] [尾頁] ";
}
echo $str;
}
}
?>
<?php
require_once 'SubPages.php';
// 模擬資料
$page_size = 20; // 每頁筆數
$total_rows = 1024; // 總筆數 (實際應用用 SELECT COUNT(*))
$sub_pages = 10; // 顯示頁碼數
$current = isset($_GET['p']) ? $_GET['p'] : 1;
$link_prefix = 'list.php?p=';
// 實例化即自動輸出分頁 HTML (模式 2)
new SubPages($page_size, $total_rows, $current, $sub_pages, $link_prefix, 2);
// 實際查詢資料
$offset = ($current - 1) * $page_size;
$sql = "SELECT * FROM articles LIMIT $offset, $page_size";
// ... 執行查詢並輸出列表 ...
?>
共 1024 條記錄,每頁顯示 20 條,當前第 1/52 頁 [首頁] [上一頁] [下一頁] [尾頁]當前第 3/52 頁 [首頁] [上一頁] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [下一頁] [尾頁]目標:在總頁數 N、顯示頁碼數 K、當前頁 P 下,產生長度為 min(K, N) 的連續頁碼陣列。
此邏輯確保使用者永遠能看到連續的頁碼,且當前頁盡量置中,首尾不會出現斷裂。
subPage_link 改為 callable,支援路由系統 (如 fn($page) => url('list', ['p'=>$page]))。data-page 屬性與 JS 事件綁定,配合 fetch() 實現無刷新翻頁。rel="prev/next"、canonical 標籤輸出方法。SubPages 類別以約 100 行程式碼實現了生產級分頁需求:邏輯清晰、參數化配置、雙模式切換、邊界條件處理完善。直接複製到專案即可使用,或作為更複雜分頁元件的基礎骨架。