分頁核心參數
$PageSize:每頁記錄數(如 10)。
$CurrentPageID:當前頁碼(從 URL 獲取,默認 1)。
$TotalRecords:總記錄數(SELECT COUNT(*))。
$TotalPages = ceil($TotalRecords / $PageSize):總頁數。
MySQL LIMIT 语法
SELECT * FROM table LIMIT offset, rows
-- 第 1 頁: LIMIT 0, 10
-- 第 2 頁: LIMIT 10, 10
-- 第 N 頁: LIMIT (N-1)*PageSize, PageSize
完整基礎代碼
<?php
$link = mysqli_connect("localhost", "user", "pass", "db") or die("連接失敗: " . mysqli_connect_error());
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$pageSize = 10;
// 獲取總數
$totalRes = mysqli_query($link, "SELECT COUNT(*) AS cnt FROM articles");
$totalRow = mysqli_fetch_assoc($totalRes);
$totalRecords = $totalRow['cnt'];
$totalPages = ceil($totalRecords / $pageSize);
// 獲取當前頁數據
$offset = ($page - 1) * $pageSize;
$dataRes = mysqli_query($link, "SELECT * FROM articles ORDER BY id DESC LIMIT $offset, $pageSize");
?>
<table>
<tr><th>ID</th><th>標題</th><th>時間</th></tr>
<?php while ($row = mysqli_fetch_assoc($dataRes)): ?>
<tr>
<td><?=$row['id']?></td>
<td><?=htmlspecialchars($row['title'])?></td>
<td><?=$row['created_at']?></td>
</tr>
<?php endwhile; ?>
</table>
<div class="pagination">
<?php
// 上一頁
if ($page > 1) echo '<a href="?page='.($page-1).'">上一頁</a> ';
// 數字頁碼(簡易版:最多顯示 5 個)
$start = max(1, $page - 2);
$end = min($totalPages, $page + 2);
for ($i = $start; $i <= $end; $i++) {
$class = ($i == $page) ? ' class="current"' : '';
echo "<a href=\"?page=$i\"$class>$i</a> ";
}
// 下一頁
if ($page < $totalPages) echo '<a href="?page='.($page+1).'">下一頁</a>';
?>
</div>
<?php
mysqli_free_result($dataRes);
mysqli_free_result($totalRes);
mysqli_close($link);
?>
進階優化方向
- 使用
SQL_CALC_FOUND_ROWS + FOUND_ROWS() 減少一次 COUNT 查詢(MySQL 特有)。
- 大數據量避免
OFFSET 深分頁性能問題,改用游標分頁(WHERE id > last_id LIMIT 10)。
- URL 重寫美化:
/page/3 而非 ?page=3。
- 前端 AJAX 無刷新翻頁,配合 History API 更新 URL。
- 緩存總數與首頁數據(Redis/Memcached),降低 DB 壓力。