SELECT * FROM table LIMIT offset, count
offset:起始行號(從 0 開始)count:每頁顯示行數頁碼 page(從 1 開始)轉換公式:
$offset = ($page - 1) * $pageSize;
<?php
// 1. 獲取並驗證頁碼
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
$pageSize = 10;
// 2. 數據庫連接 (PDO 推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 3. 獲取總記錄數
$total = $pdo->query("SELECT COUNT(*) FROM `table`")->fetchColumn();
$pageCount = (int)ceil($total / $pageSize);
// 4. 邊界檢查
if ($page > $pageCount) { $page = $pageCount; }
if ($page < 1) { $page = 1; }
// 5. 計算偏移量並查詢
$offset = ($page - 1) * $pageSize;
$stmt = $pdo->prepare("SELECT * FROM `table` ORDER BY `id` DESC LIMIT :offset, :size");
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':size', $pageSize, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 6. 輸出數據
foreach ($rows as $row) {
echo htmlspecialchars($row['name']) . "<br>";
}
// 7. 生成頁碼導航
$nav = '';
for ($i = 1; $i <= $pageCount; $i++) {
$nav .= ($i == $page)
? " <strong>$i</strong> "
: " <a href='?page=$i'>$i</a> ";
}
echo "<div class='pagination'>$nav</div>";
?>
| 問題 | 解決方案 |
|---|---|
| 深分頁性能劣化 (OFFSET 大) | 使用 游標分頁:WHERE id > :last_id ORDER BY id LIMIT 10,需配合唯一遞增索引 |
| COUNT(*) 全表掃描慢 | 資訊表近似值 SHOW TABLE STATUS、緩存總數、觸發器維護計數表、或接受估算值 |
| 未指定 ORDER BY 導致結果不穩定 | 必須加 ORDER BY(如 id DESC),確保分頁順序確定性 |
| SQL 注入風險 | 全程使用預處理語句(PDO/MySQLi) |
function build_pager($page, $pageCount, $urlPattern, $showPages = 9) {
$half = (int)($showPages / 2);
$start = max(1, $page - $half);
$end = min($pageCount, $start + $showPages - 1);
$start = max(1, $end - $showPages + 1); // 重新校正
$html = '';
if ($page > 1) {
$html .= "<a href='" . sprintf($urlPattern, 1) . "'>首頁</a> ";
$html .= "<a href='" . sprintf($urlPattern, $page - 1) . "'>上一頁</a> ";
}
if ($start > 1) $html .= "<a href='" . sprintf($urlPattern, 1) . "'>1</a> ... ";
for ($i = $start; $i <= $end; $i++) {
$html .= ($i == $page) ? " <span class='current'>$i</span> " : " <a href='" . sprintf($urlPattern, $i) . "'>$i</a> ";
}
if ($end < $pageCount) $html .= "... <a href='" . sprintf($urlPattern, $pageCount) . "'>$pageCount</a> ";
if ($page < $pageCount) {
$html .= "<a href='" . sprintf($urlPattern, $page + 1) . "'>下一頁</a> ";
$html .= "<a href='" . sprintf($urlPattern, $pageCount) . "'>尾頁</a> ";
}
return $html;
}
// 用法:echo build_pager($page, $pageCount, '?page=%d');
總頁數 = ceil(總記錄數 / 每頁條數)
offset = (page - 1) * pageSize
LIMIT offset, pageSize
必須 ORDER BY 確定排序