首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 簡易分頁類實現與最佳實踐指南

     編輯:PHP 相關知識

分頁邏輯核心數學模型

分頁本質上是對數據集進行切片。核心參數只有三個:總記錄數 ($total)、當前頁碼 ($page)、每頁條數 ($num)。由此推導出所有顯示所需數據:

  • 總頁數 = ceil($total / $num)
  • 數據庫偏移量 (OFFSET) = ($page - 1) * $num
  • 當前頁起始序號 = $offset + 1 (若 $total > 0)
  • 當前頁結束序號 = min($offset + $num, $total)
  • 上一頁 / 下一頁:邊界判斷 (首頁無上一頁,尾頁無下一頁)

Page 類完整實現 (PHP 5.3+ 語法)

採用封裝性設計,構造函數初始化計算,對外僅暴露 getPageInfo() 返回關聯陣列,便於模板引擎直接渲染。

<?php
/**
 * 簡易分頁計算類
 * 職責:純粹計算分頁參數,不輸出 HTML,不依賴數據庫
 */
class Page
{
    private $total;       // 總記錄數
    private $page;        // 當前頁碼
    private $num;         // 每頁條數
    private $pageNum;     // 總頁數
    private $offset;      // SQL LIMIT 偏移量

    /**
     * 構造函數
     * @param int $total   總記錄數 (必填)
     * @param int $page    當前頁碼 (默認 1)
     * @param int $num     每頁條數 (默認 10)
     */
    public function __construct($total, $page = 1, $num = 10)
    {
        $this->total = max(0, (int)$total);
        $this->num   = max(1, (int)$num);
        $this->page  = max(1, (int)$page);

        $this->pageNum = $this->calculatePageNum();
        // 修正頁碼超出範圍
        if ($this->page > $this->pageNum && $this->pageNum > 0) {
            $this->page = $this->pageNum;
        }
        $this->offset = $this->calculateOffset();
    }

    private function calculatePageNum()
    {
        return (int)ceil($this->total / $this->num);
    }

    private function calculateOffset()
    {
        return ($this->page - 1) * $this->num;
    }

    /**
     * 獲取完整分頁信息陣列,供模板使用
     * @return array
     */
    public function getPageInfo()
    {
        return [
            'row_total'    => $this->total,
            'row_num'      => $this->num,
            'page_num'     => $this->pageNum,
            'current_page' => $this->page,
            'row_offset'   => $this->offset,           // SQL LIMIT offset
            'next_page'    => ($this->page < $this->pageNum) ? $this->page + 1 : false,
            'prev_page'    => ($this->page > 1) ? $this->page - 1 : false,
            'page_start'   => ($this->total > 0) ? $this->offset + 1 : 0, // 顯示用起始序號
            'page_end'     => min($this->offset + $this->num, $this->total), // 顯示用結束序號
        ];
    }
}
?>

控制器中調用示例

<?php
// 1. 獲取總數 (Model 層)
$total = $db->query("SELECT COUNT(*) FROM article")->fetchColumn();

// 2. 實例化分頁類
$currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$pageSize = 15; // 每頁 15 條
$page = new Page($total, $currentPage, $pageSize);
$pageInfo = $page->getPageInfo();

// 3. 獲取當前頁數據 (Model 層)
$offset = $pageInfo['row_offset'];
$limit  = $pageInfo['row_num'];
$articles = $db->query("SELECT * FROM article ORDER BY id DESC LIMIT $offset, $limit")->fetchAll();

// 4. 分配給模板
$tpl->assign('articles', $articles);
$tpl->assign('page', $pageInfo);
$tpl->display('article_list.tpl');
?>

前端模板渲染策略 (Smarty / Blade / 原生 PHP)

分頁類不輸出 HTML,由模板控制顯示樣式,實現邏輯與視圖分離。

{* Smarty 模板片段 *}

進階優化建議

  1. 大數據量優化:當表超過百萬行,LIMIT offset, num 深分頁性能急劇下降。解決方案:游標分頁 (Keyset Pagination) — 記住上一頁最後一條記錄的 ID,查詢 WHERE id > last_id ORDER BY id LIMIT num。
  2. URL 參數保持:分頁鏈接應保留當前搜索/過濾參數 (如 ?keyword=php&status=1&page=2),可用 http_build_query(array_merge($_GET, ['page' => $p])) 生成。
  3. SEO 友好:首頁可不帶 page=1;添加 <link rel="prev" href="..."> / rel="next" 標籤。
  4. 緩存總數:高並發下,COUNT(*) 可緩存至 Redis (過期時間 1-5 分鐘),減輕數據庫壓力。

總結

一個優秀的分頁類應職責單一:只負責數學計算,不操作數據庫、不輸出 HTML、不依賴全局變量。Page 類通過構造函數注入參數,暴露 getPageInfo() 返回標準陣列,極易於單元測試和模板渲染,是現代 PHP 開發中分頁邏輯的標準實現方式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved