功能特性
- 雙模式:直接接受 SQL 查詢字符串(自動追加 LIMIT)或 PHP 數組(自動 array_slice)。
- 自動計算總行數、總頁數、當前頁碼(從
$_GET['cur_page'] 獲取)。
- 智能分頁導航:首頁、上一頁、頁碼區間(居中顯示)、下一頁、末頁。
- 分頁信息條:總記錄數、每頁條數、總頁數、當前頁。
- 完整保持原有 URL 參數(去除舊 cur_page 後重新拼接)。
- 樣式可通過類屬性自定義(CSS 類、按鈕文本、字體顏色)。
類代碼
<?php
class PageBreak {
private $totalRows = 0;
private $curPage = 1;
private $totalPages = 1;
private $queryString = '';
private $pageRows = 20;
private $indexBarLength = 5;
private $indexBar = '';
private $pageInfo = '';
// 樣式屬性(可外部覆蓋)
public $nextBtn = '>';
public $prevBtn = '<';
public $firstBtn = '|<';
public $lastBtn = '>|';
public $cssCurPage = 'font-weight:bold;color:#F00;';
public $cssPage = '';
public $cssInfoNum = 'color:#F00;';
public $cssInfo = '';
public function __construct(&$sqlOrArray, $pageRows = '') {
if (is_array($sqlOrArray)) {
$this->setArrayPage($sqlOrArray, $pageRows);
} else {
$this->setDbPage($sqlOrArray, $pageRows);
}
}
private function setDbPage(&$sql, $pageRows) {
$this->totalRows = mysql_num_rows(mysql_query($sql));
$this->calcPages($pageRows);
if ($this->totalPages > 1) {
$this->curPage = max(1, min((int)($_GET['cur_page'] ?? 1), $this->totalPages));
$this->applyLimit($sql);
$this->buildQueryString();
$this->buildBars();
}
}
private function setArrayPage(&$arr, $pageRows) {
$this->totalRows = count($arr);
$this->calcPages($pageRows);
if ($this->totalPages > 1) {
$this->curPage = max(1, min((int)($_GET['cur_page'] ?? 1), $this->totalPages));
$start = ($this->curPage - 1) * $this->pageRows;
$arr = array_slice($arr, $start, $this->pageRows);
$this->buildQueryString();
$this->buildBars();
}
}
private function calcPages($pageRows) {
if ($pageRows) $this->pageRows = $pageRows;
$this->totalPages = (int)ceil($this->totalRows / $this->pageRows);
}
private function applyLimit(&$sql) {
$start = ($this->curPage - 1) * $this->pageRows;
$sql .= " LIMIT $start,{$this->pageRows}";
}
private function buildQueryString() {
$qs = $_SERVER['QUERY_STRING'] ?? '';
$qs = preg_replace('/&?cur_page=\d+/', '', $qs);
$this->queryString = '?' . ($qs ? $qs . '&' : '') . 'cur_page=';
}
private function buildBars() {
$this->pageInfo = "<span style='{$this->cssInfo}'>";
$this->pageInfo .= "共 <span style='{$this->cssInfoNum}'>{$this->totalRows}</span> 條 | ";
$this->pageInfo .= "每頁 <span style='{$this->cssInfoNum}'>{$this->pageRows}</span> 條 | ";
$this->pageInfo .= "共 <span style='{$this->cssInfoNum}'>{$this->totalPages}</span> 頁 | ";
$this->pageInfo .= "第 <span style='{$this->cssInfoNum}'>{$this->curPage}</span> 頁";
$this->pageInfo .= "</span> ";
$this->indexBar = $this->navBtn($this->firstBtn, 1);
$this->indexBar .= $this->navBtn($this->prevBtn, max(1, $this->curPage - 1));
$this->indexBar .= $this->pageNumbers();
$this->indexBar .= $this->navBtn($this->nextBtn, min($this->totalPages, $this->curPage + 1));
$this->indexBar .= $this->navBtn($this->lastBtn, $this->totalPages);
}
private function pageNumbers() {
$half = (int)floor($this->indexBarLength / 2);
if ($this->totalPages <= $this->indexBarLength) {
$start = 1; $end = $this->totalPages;
} elseif ($this->curPage - $half <= 1) {
$start = 1; $end = $this->indexBarLength;
} elseif ($this->curPage + $half >= $this->totalPages) {
$start = $this->totalPages - $this->indexBarLength + 1; $end = $this->totalPages;
} else {
$start = $this->curPage - $half; $end = $this->curPage + $half;
}
$html = '';
for ($i = $start; $i <= $end; $i++) {
if ($i == $this->curPage) {
$html .= "<span style='{$this->cssCurPage}'>$i</span> ";
} else {
$html .= "<a href='{$this->queryString}$i' style='{$this->cssPage}'>$i</a> ";
}
}
return $html;
}
private function navBtn($text, $page) {
return "<a href='{$this->queryString}$page'>$text</a> ";
}
public function getIndexBar() { return $this->indexBar; }
public function getPageInfo() { return $this->pageInfo; }
}
?>
使用示例
模式一:配合數據庫查詢(SQL 自動追加 LIMIT)
<?php
require 'PageBreak.class.php';
$sql = "SELECT * FROM articles WHERE status=1 ORDER BY id DESC";
$page = new PageBreak($sql, 15); // 每頁 15 條
// $sql 現在已包含 LIMIT 子句
$articles = $db->getAll($sql); // 假設自有 DB 類
echo $page->getPageInfo() . $page->getIndexBar();
foreach ($articles as $art) {
echo "<h3>{$art['title']}</h3><p>{$art['summary']}</p>";
}
?>
模式二:配合已獲取的數組
<?php
$all = $db->getAll("SELECT * FROM products WHERE cat_id=5");
$page = new PageBreak($all, 20); // $all 被截取為當前頁數據
echo $page->getPageInfo() . $page->getIndexBar();
foreach ($all as $p) { echo $p['name'] . '<br>'; }
?>
自定義樣式
$page = new PageBreak($sql, 10);
$page->nextBtn = 'Next >';
$page->prevBtn = '< Prev';
$page->firstBtn = 'First';
$page->lastBtn = 'Last';
$page->cssCurPage = 'background:#F00;color:#FFF;padding:2px 6px;border-radius:3px;';
$page->cssPage = 'color:#333;text-decoration:none;margin:0 2px;';
echo $page->getPageInfo() . $page->getIndexBar();
遷移建議(PHP 7+ / PDO)
- 將
mysql_* 替換為 PDO:$pdo->query($sql)->rowCount() 獲取總行數(或單獨 COUNT(*) 查詢更高效)。
- 構造函數接受
PDOStatement 或回調函數獲取總數,避免 SQL 注入風險。
- 輸出 HTML 時使用模板引擎或獨立視圖文件,不在類中硬編碼 HTML。