分頁功能是 Web 應用的標配組件。一個優秀的分頁類不僅要處理資料庫查詢邏輯,更應提供靈活的前端顯示模式、自動處理 URL 參數、支援自定義樣式。本文呈現一個功能完整、生產可用的 PHP 分頁類 pagelist,涵蓋從資料查詢到 HTML 輸出的全流程。
class pagelist {
// 分頁參數
var $page; // 當前頁碼
var $page_size = 20; // 每頁筆數
var $num_btn = 9; // 數字按鈕顯示個數
// 資料庫與查詢
var $db; // 資料庫連線物件
var $table = array(); // 表配置:tablename, id, orderby, descasc, fileds, where
var $sql; // 自定義 SQL
// 統計資訊
var $total_records; // 總記錄數
var $total_pages; // 總頁數
// 顯示相關
var $img_path; // 圖標路徑
var $img_btn; // 圖標 HTML
var $url; // 分頁基礎 URL
}
function __construct() {
global $db;
$this->db = $db;
$tmp_page = intval(trim($_GET["page"]));
$this->page = empty($tmp_page) ? 1 : $tmp_page;
$this->set_table();
$this->page_size = 20;
$this->num_btn = 9;
$this->img_path = '/images/';
$this->img = array("ico_first.gif", "ico_front.gif", "ico_next.gif", "ico_last.gif");
}
自動從 $_GET['page'] 取得當前頁,預設為第 1 頁。初始化預設顯示參數與圖標路徑。
function set_total_records() {
if ($this->total_records == 0 or !isset($this->total_records)) {
if (empty($this->count_sql) and !empty($this->table["tablename"])) {
$sql = "SELECT count(".$this->table["id"].") as count_id
FROM `".$this->table["tablename"]."`
".($this->table["where"]!="" ? " WHERE ".$this->table["where"] : "");
} else {
$sql = preg_replace("/SELECT(.*?)FROM(.*?)/i",
"SELECT count(id) AS count_id FROM\\2", $this->sql);
}
$arr = $this->db->row_query_one($sql);
$this->total_records = $arr["count_id"];
}
}
function set_show_page() {
$this->set_img();
$this->set_url();
$this->set_total_records();
if ($this->total_records < $this->page_size) {
$this->total_pages = 1;
} else {
$this->total_pages = ceil($this->total_records / $this->page_size);
}
if ($this->page > $this->total_pages) {
$this->page = $this->total_pages;
}
}
支援兩種計數方式:基於表配置自動生成 COUNT SQL,或基於自定義 SQL 透過正則轉換。自動修正超出範圍的頁碼。
function set_url() {
$arr_url = array();
parse_str($_SERVER["QUERY_STRING"], $arr_url);
unset($arr_url["page"]);
if (empty($arr_url)) {
$str = "page=";
} else {
$str = http_build_query($arr_url)."&page=";
}
$this->url = "https://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"]."?".$str;
}
自動保留所有查詢參數(搜尋關鍵字、篩選條件等),僅替換 page 參數,確保分頁連結不丟失查詢上下文。
類提供模組化的顯示方法,可自由組合:
show_first_prv():首頁/上一頁圖標(當前頁為 1 時禁用)show_next_last():下一頁/末頁圖標(當前頁為末頁時禁用)show_num_btn():核心數字按鈕邏輯,實現以當前頁為中心的滑動窗口顯示show_num_select():下拉選單跳轉(總頁數 < 50 時顯示)show_num_text():輸入框 + Go 按鈕直接跳轉show_page_info():顯示「共 X 條 / Y 頁」統計資訊function get_sql() {
if ($this->total_records > 10000) {
$this->sql = "SELECT ".$this->table["fileds"]." FROM `".$this->table["tablename"]."`
".($this->table["where"]!="" ? " WHERE ".$this->table["where"].' AND '.$this->table["id"].'>=' : ' WHERE '.$this->table["id"].'>=')
."(SELECT ".$this->table["id"]." FROM `".$this->table["tablename"]."`
ORDER BY ".$this->table["id"]." LIMIT ".$this->page_size*($this->page-1).", 1)
ORDER BY ".$this->table["orderby"]." ".$this->table["descasc"]."
LIMIT ".$this->page_size;
} else {
$this->sql = "SELECT ".$this->table["fileds"]." FROM `".$this->table["tablename"]."`
".($this->table["where"]!="" ? " WHERE ".$this->table["where"] : "")
." ORDER BY ".$this->table["orderby"]." ".$this->table["descasc"]
." LIMIT ".$this->page_size*($this->page-1).", ".$this->page_size;
}
return $this->sql;
}
當總記錄數超過 10,000 筆,自動切換至子查詢模式(延遲關聯),避免大偏移量 LIMIT 的效能陷阱。
<?php
include('db.php');
include('pagelist.php');
$db = new db();
$db->connect($db_config);
header("content-type:text/html;charset=utf-8");
$pl = new pagelist();
$arr = $pl->get_rows('table_name'); // 表名,可選 where、orderby
unset($pl);
echo '<pre style="text-align:left">';
print_r($arr);
echo '</pre>';
// 輸出分頁導航:$arr['page']
// 輸出資料列表:$arr['rows']
// 總筆數:$arr['sum']
?>
$pl = new pagelist();
$sql = 'SELECT * FROM `wap_article` AS a, `wap_article_info` AS b WHERE a.id=b.articleid';
$arr = $pl->get_rows_sql($sql); // 需自行確保 SQL 包含排序
unset($pl);
// 同樣回傳包含 page、rows、sum 的陣列
?>
類註釋中包含建議的 CSS 樣式(.page 系列),可直接引用或自定義:
.page { float: left; font: 11px Arial, Helvetica, sans-serif; padding: 6px 0; margin: 0px 10%; margin-top: 10px; }
.page a, .page strong { padding: 2px 6px; border: solid 1px #ddd; background: #fff; text-decoration: none; }
.page a:visited { padding: 2px 6px; border: solid 1px #ddd; background: #fff; text-decoration: none; }
.page .break { padding: 2px 6px; border: none; background: #fff; text-decoration: none; }
.page strong { padding: 2px 6px; border-color: #999; font-weight: bold; font-size: 13px; vertical-align: top; background: #fff; }
.page a:hover { color: #fff; background: #0063DC; border-color: #036; text-decoration: none; }
這個 pagelist 類經過實戰驗證,具備:
可直接整合至任何 PHP + MySQL 專案,或作為二次開發基礎進一步封裝為現代框架(Laravel、ThinkPHP 等)的分頁元件。