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

PHP 分頁功能三種實現方案:類封裝、AJAX 無刷新、原生 LIMIT 邏輯詳解

     編輯:PHP 相關知識

方案一:面向對象分頁類(傳統頁面跳轉)

Pager 類核心代碼

class Pager {
    public $sql, $datanum, $page_size;
    private $_conn, $_query_id, $_errstr;

    public function __construct($sql, $page_size) {
        $result = mysql_query($sql);
        $this->datanum = mysql_num_rows($result);
        $this->sql = $sql;
        $this->page_size = $page_size;
    }

    // 當前頁碼(從 QUERY_STRING 解析)
    public function page_id() {
        if (empty($_SERVER['QUERY_STRING'])) return 1;
        if (strpos($_SERVER['QUERY_STRING'], 'page_id=') === false) return 1;
        return (int)substr($_SERVER['QUERY_STRING'], 8);
    }

    // 剩餘 URL 參數(保留其他查詢條件)
    public function url() {
        if (empty($_SERVER['QUERY_STRING'])) return '';
        if (strpos($_SERVER['QUERY_STRING'], 'page_id=') === false) 
            return '&' . $_SERVER['QUERY_STRING'];
        return str_replace('page_id=' . $this->page_id(), '', $_SERVER['QUERY_STRING']);
    }

    // 總頁數
    public function page_num() {
        return $this->datanum == 0 ? 1 : ceil($this->datanum / $this->page_size);
    }

    // LIMIT 偏移量
    public function start() {
        return ($this->page_id() - 1) * $this->page_size;
    }

    // 帶 LIMIT 的查詢 SQL
    public function sqlquery() {
        return $this->sql . " LIMIT " . $this->start() . ", " . $this->page_size;
    }

    // 生成分頁導航 HTML
    public function set_page_info() {
        $html = "共 {$this->datanum} 條 ";
        $html .= $this->link(1, '首頁');
        $html .= $this->page_id() == 1 ? '上一頁' : $this->link($this->page_id() - 1, '上一頁');
        
        $html .= $this->page_numbers();
        
        $html .= $this->page_id() == $this->page_num() ? '下一頁' : $this->link($this->page_id() + 1, '下一頁');
        $html .= $this->link($this->page_num(), '尾頁');
        $html .= " 第 {$this->page_id()} / {$this->page_num()} 頁";
        return $html;
    }

    private function link($page, $text) {
        return '' . $text . ' ';
    }

    private function page_numbers() {
        $total = $this->page_num();
        $current = $this->page_id();
        $html = '';

        if ($total <= 10) {
            for ($i = 1; $i <= $total; $i++) $html .= $this->link($i, $i);
        } elseif ($current <= 6) {
            for ($i = 1; $i <= 10; $i++) $html .= $this->link($i, $i);
        } elseif ($total - $current >= 4) {
            for ($i = $current - 5; $i <= $current + 4; $i++) $html .= $this->link($i, $i);
        } else {
            for ($i = $total - 9; $i <= $total; $i++) $html .= $this->link($i, $i);
        }
        return $html;
    }
}

使用示例

require 'Pager.class.php';

$conn = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('db', $conn);
mysql_query('SET NAMES utf8');

$sql = "SELECT word FROM spam_accuse_word_list WHERE flag='0'";
$pager = new Pager($sql, 20);

$result = mysql_query($pager->sqlquery());
while ($row = mysql_fetch_assoc($result)) {
    echo $row['word'] . '
'; } echo $pager->set_page_info();

方案二:AJAX 無刷新分頁(現代體驗)

核心原理:LIMIT 邏輯

-- 第 1 頁:LIMIT 0, 10
-- 第 2 頁:LIMIT 10, 10
-- 第 n 頁:LIMIT (n-1)*size, size
SELECT * FROM table LIMIT (), 

前端 JS(jQuery)

function loadPage(page) {
    $.get('ajax_list.php', {page: page, size: 20}, function(html) {
        $('#list').html(html.list);
        $('#pager').html(html.pager);
    }, 'json');
}

$(document).on('click', '.page-link', function(e) {
    e.preventDefault();
    loadPage($(this).data('page'));
});

後端 ajax_list.php

$page = max(1, (int)($_GET['page'] ?? 1));
$size = min(100, max(1, (int)($_GET['size'] ?? 20)));
$offset = ($page - 1) * $size;

$total = (int)mysql_result(mysql_query("SELECT COUNT(*) FROM message"), 0);
$pages = ceil($total / $size);

$data = mysql_query("SELECT * FROM message ORDER BY id DESC LIMIT $offset, $size");
$list = '';
while ($row = mysql_fetch_assoc($data)) {
    $list .= "
{$row['title']} - {$row['content']}
"; } // 生成分頁 HTML(同 Pager 類邏輯,輸出字符串) $pagerHtml = generatePagerHtml($page, $pages, $_SERVER['REQUEST_URI']); echo json_encode(['list' => $list, 'pager' => $pagerHtml, 'total' => $total]);

方案三:原生 $_SERVER 解析 + parse_url(輕量級)

$pageSize = 2;
$url = $_SERVER['REQUEST_URI'];
$parsed = parse_url($url);
$path = $parsed['path'];  // 去除查詢字符串

$total = mysql_result(mysql_query("SELECT COUNT(*) FROM message"), 0);
$totalPages = ceil($total / $pageSize);

$page = isset($_GET['page']) ? max(1, min((int)$_GET['page'], $totalPages)) : 1;
$offset = ($page - 1) * $pageSize;

$result = mysql_query("SELECT * FROM message LIMIT $offset, $pageSize");
// ... 輸出數據 ...

// 簡易分頁鏈接
for ($i = 1; $i <= $totalPages; $i++) {
    $qs = http_build_query(array_merge($_GET, ['page' => $i]));
    echo "$i ";
}

三大方案對比

維度方案一:類封裝方案二:AJAX方案三:原生輕量
代碼復用性高(類封裝)中(需前後端協作)低(邏輯分散)
用戶體驗頁面跳轉無刷新,流暢頁面跳轉
SEO 友好佳(獨立 URL)需額外處理(History API/SSR)佳
適用場景後台管理、內容列表前台列表、無限滾動預載簡單項目、快速原型
維護成本低中高(邏輯重複)

生產環境優化清單

  1. 計數優化:大表用 COUNT(*) 慢,考慮緩存總數、觸發器維護計數表、或 EXPLAIN 估算行數
  2. 深分頁優化:LIMIT 100000, 20 掃描 10 萬行,改用 WHERE id > last_id LIMIT 20(游標分頁)
  3. 索引覆蓋:查詢字段含索引列,避免回表
  4. 緩存首頁:首頁數據緩存 1-5 分鐘,抗峰值流量
  5. 防刷保護:限制單 IP 分頁請求頻率

總結

PHP 分頁核心是 LIMIT offset, size。方案一類封裝適合傳統多頁應用,代碼復用性強;方案二AJAX提升前端體驗,配合 History API 解決 SEO;方案三原生邏輯適合快速驗證。生產環境務必關注深分頁性能、計數緩存、索引設計三大塊,並根據業務選型。

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