分頁是 Web 應用中處理大量資料的核心機制。本文將從傳統 mysql_* 函式庫的教學範例出發,逐步重構為符合現代標準的 PDO 版本,並說明關鍵邏輯與安全性考量。
無論使用何種資料庫介面,分頁的數學模型皆相同:
SELECT COUNT(*) FROM tableceil(總筆數 / 每頁筆數)($currentPage - 1) * $pageSizeSELECT * FROM table LIMIT $offset, $pageSize<?php
// config/database.php 回傳 PDO 實例
$pdo = require 'config/database.php';
$pageSize = 10;
$pageNow = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
// 取得總筆數
$stmt = $pdo->query("SELECT COUNT(*) FROM user");
$totalRows = $stmt->fetchColumn();
$totalPages = (int)ceil($totalRows / $pageSize);
// 修正頁碼範圍
$pageNow = min($pageNow, max(1, $totalPages));
// 查詢當頁資料
$offset = ($pageNow - 1) * $pageSize;
$stmt = $pdo->prepare("SELECT user_name, name, email, tel FROM user LIMIT :offset, :limit");
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':limit', $pageSize, PDO::PARAM_INT);
$stmt->execute();
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>用戶列表</title></head>
<body>
<table border="1">
<tr><th>帳號</th><th>姓名</th><th>Email</th><th>電話</th></tr>
<?php foreach ($users as $user): ?>
<tr>
<td><?= htmlspecialchars($user['user_name']) ?></td>
<td><?= htmlspecialchars($user['name']) ?></td>
<td><?= htmlspecialchars($user['email']) ?></td>
<td><?= htmlspecialchars($user['tel']) ?></td>
</tr>
<?php endforeach; ?>
</table>
<div class="pagination">
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
<a href="?page=<?= $i ?>" class="<?= $i === $pageNow ? 'active' : '' ?>"><?= $i ?></a>
<?php endfor; ?>
</div>
</body>
</html>
htmlspecialchars() 防範 XSS 攻擊。COUNT(*) 可能較慢,可考慮快取總筆數或使用近似值。OFFSET 效能差,建議改用游標分頁(WHERE id > last_id LIMIT 10)。