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

PHP 分頁列表頁完整實現:從資料庫查詢到分頁導航的現代化重構

     編輯:PHP 相關知識

核心需求

構建一個完整的分頁列表頁,包含資料查詢、分頁邏輯、頁碼導航生成,並採用現代 PHP 最佳實踐(PDO、預處理語句、關注點分離)。

資料庫準備(MySQL 範例)

CREATE TABLE `persons` (
    `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    `first_name` VARCHAR(50) NOT NULL,
    `last_name` VARCHAR(50) NOT NULL,
    `email` VARCHAR(100),
    `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

核心分頁類實現

<?php
class Paginator
{
    private PDO $pdo;
    private int $perPage;
    private string $baseUrl;

    public function __construct(PDO $pdo, int $perPage = 10, string $baseUrl = '')
    {
        $this->pdo = $pdo;
        $this->perPage = $perPage;
        $this->baseUrl = $baseUrl ?: $_SERVER['PHP_SELF'];
    }

    public function paginate(string $table, array $conditions = [], array $params = []): array
    {
        $page = max(1, (int)($_GET['page'] ?? 1));
        $offset = ($page - 1) * $this->perPage;

        // 構建 WHERE 子句
        $whereSql = '';
        if ($conditions) {
            $whereSql = 'WHERE ' . implode(' AND ', $conditions);
        }

        // 總筆數查詢
        $countSql = "SELECT COUNT(*) FROM `{$table}` {$whereSql}";
        $stmt = $this->pdo->prepare($countSql);
        $stmt->execute($params);
        $total = (int)$stmt->fetchColumn();

        // 分頁數據查詢
        $dataSql = "SELECT * FROM `{$table}` {$whereSql} ORDER BY `id` DESC LIMIT {$offset}, {$this->perPage}";
        $stmt = $this->pdo->prepare($dataSql);
        $stmt->execute($params);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        return [
            'data' => $rows,
            'pagination' => $this->buildPagination($total, $page),
        ];
    }

    private function buildPagination(int $total, int $currentPage): array
    {
        $totalPages = (int)ceil($total / $this->perPage);
        $range = 3; // 當前頁前後顯示頁碼數
        $start = max(1, $currentPage - $range);
        $end = min($totalPages, $currentPage + $range);

        $pages = [];
        if ($currentPage > 1) {
            $pages[] = ['page' => 1, 'label' => '首頁', 'active' => false];
            $pages[] = ['page' => $currentPage - 1, 'label' => '上一頁', 'active' => false];
        }

        for ($i = $start; $i <= $end; $i++) {
            $pages[] = ['page' => $i, 'label' => (string)$i, 'active' => $i === $currentPage];
        }

        if ($currentPage < $totalPages) {
            $pages[] = ['page' => $currentPage + 1, 'label' => '下一頁', 'active' => false];
            $pages[] = ['page' => $totalPages, 'label' => '尾頁', 'active' => false];
        }

        return [
            'current' => $currentPage,
            'total' => $totalPages,
            'count' => $total,
            'per_page' => $this->perPage,
            'links' => $pages,
        ];
    }
}

控制器使用範例

<?php
require_once 'Paginator.php';

$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);

$paginator = new Paginator($pdo, 5);
$result = $paginator->paginate('persons');

$rows = $result['data'];
$pagination = $result['pagination'];
?>

<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <title>用戶列表</title>
    <style>
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        .pagination { display: flex; gap: 5px; justify-content: center; margin-top: 20px; }
        .pagination a, .pagination span { padding: 8px 12px; border: 1px solid #ddd; text-decoration: none; }
        .pagination .active { background: #007bff; color: white; border-color: #007bff; }
    </style>
</head>
<body>
    <h1>用戶列表 (共  筆)</h1>
    <table>
        <thead>
            <tr><th>ID</th><th>姓名</th><th>Email</th><th>建立時間</th></tr>
        </thead>
        <tbody>
            
            <tr>
                <td></td>
                <td></td>
                <td></td>
                <td></td>
            </tr>
            
        </tbody>
    </table>

    <div class="pagination">
        
            
                <span class="active"></span>
            
                <a href="baseUrl . '?page=' . $link['page']; ?>">
                    
                </a>
            
        
    </div>
</body>
</html>

關鍵改進點總結

  • 棄用 mysql_*:改用 PDO + 預處理語句,防止 SQL 注入。
  • 關注點分離:分頁邏輯封裝於 Paginator 類,視圖模板純粹負責渲染。
  • 靈活的條件查詢:支援動態 WHERE 條件與參數綁定。
  • 語義化分頁結構:輸出結構化陣列,前端易於自定義樣式(Bootstrap、Tailwind 等)。
  • XSS 防護:所有輸出經 htmlspecialchars() 轉義。

此架構易於擴展為 API 介面(返回 JSON)、加入快取層、或整合至 Laravel、Symfony 等框架的分頁組件中。

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