<< < 1 2 3 4 > >>)<?php
//---[ 資料庫連線 ]---
$conn = mysql_connect("localhost", "root", "");
mysql_select_db("test", $conn);
//---[ 分頁核心參數 ]---
$perPage = 2; // 每頁筆數
// 取得總筆數
$sqlCount = "SELECT COUNT(*) AS total FROM test";
$rsCount = mysql_query($sqlCount, $conn);
$rowCount = mysql_fetch_assoc($rsCount);
$totalRows = $rowCount['total'];
$totalPages = ceil($totalRows / $perPage);
// 當前頁碼驗證
if (!isset($_GET['page']) || !intval($_GET['page']) || $_GET['page'] > $totalPages) {
$page = 1;
} else {
$page = intval($_GET['page']);
}
$offset = ($page - 1) * $perPage;
// 取得當頁資料
$sql = "SELECT * FROM test LIMIT $offset, $perPage";
$result = mysql_query($sql, $conn);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="gb2312">
<title>PHP 分頁示例</title>
<style>
table {width:30%; border-collapse:collapse; margin:0 auto; font-size:12px;}
th, td {border:1px solid #73BB95; padding:5px; text-align:center;}
th {background:#73BB95; color:#fff;}
a {text-decoration:none; color:#333; margin:0 3px;}
a:hover {text-decoration:underline; color:#f60;}
.current {color:#f00; font-weight:bold;}
select {margin-left:10px; padding:2px;}
</style>
<script>
function jumpMenu(sel) { location.href = sel.value; }
</script>
</head>
<body>
<table>
<tr><th>ID</th></tr>
<?php if ($totalRows > 0): ?>
<?php while ($row = mysql_fetch_assoc($result)): ?>
<tr><td><?=$row['id']?></td></tr>
<?php endwhile; ?>
<?php else: ?>
<tr><td>沒有任何記錄</td></tr>
<?php endif; ?>
</table>
<table width="95%" style="margin:10px auto;">
<tr><td align="center">
<?php
echo "共計 <span style='color:#f00'>$totalRows</span> 條記錄 ";
echo "<span style='color:#f00'>$page</span> / $totalPages 頁 ";
// 頁碼導航邏輯
$showPages = 4; // 顯示頁碼數量
$prePage = 1; // 當前頁前後保留頁數
// 首頁/上一頁
if ($page > 1) {
echo "<a href='{$_SERVER['PHP_SELF']}'><<</a> ";
echo "<a href='{$_SERVER['PHP_SELF']}?page=".($page-1)."'><</a> ";
}
// 計算顯示範圍
if ($showPages >= $totalPages) {
$start = 1; $end = $totalPages;
} elseif (($page - $prePage - 1 + $showPages) > $totalPages) {
$start = $totalPages - $showPages + 1;
$end = $totalPages;
} else {
$start = ($page <= $prePage) ? 1 : ($page - $prePage);
$end = ($start == 1) ? $showPages : ($start + $showPages - 1);
}
for ($p = $start; $p <= $end; $p++) {
if ($p == $page) echo "<span class='current'>$p</span> ";
else echo "<a href='{$_SERVER['PHP_SELF']}?page=$p'>$p</a> ";
}
// 下一頁/尾頁
if ($page < $totalPages) {
echo "<a href='{$_SERVER['PHP_SELF']}?page=".($page+1)."'>></a> ";
echo "<a href='{$_SERVER['PHP_SELF']}?page=$totalPages'>>></a> ";
}
?>
<select onchange="jumpMenu(this)">
<option value="">跳轉頁碼</option>
<?php for ($p = 1; $p <= $totalPages; $p++): ?>
<option value="<?=$_SERVER['PHP_SELF']?>?page=<?=$p?>" <?=$p==$page?'selected':''?>><?=$p?></option>
<?php endfor; ?>
</select>
</td></tr>
</table>
<?php
mysql_free_result($rsCount);
mysql_free_result($result);
mysql_close($conn);
?>
</body>
</html>
| 區塊 | 關鍵點 |
|---|---|
| 總頁數計算 | ceil($totalRows / $perPage) 無條件進位 |
| 頁碼驗證 | 三重防護:未設定、非整數、超出範圍 → 預設第 1 頁 |
| OFFSET 計算 | ($page - 1) * $perPage,配合 LIMIT offset, count |
| 智慧頁碼範圍 | 動態調整 $start/$end,確保當前頁在可視區中段,邊界自動修正 |
class Paginator {
private $pdo, $table, $perPage, $page, $totalRows, $totalPages;
public function __construct(PDO $pdo, $table, $perPage = 10) {
$this->pdo = $pdo; $this->table = $table; $this->perPage = $perPage;
$this->page = max(1, intval($_GET['page'] ?? 1));
$this->calcTotal();
$this->page = min($this->page, $this->totalPages ?: 1);
}
private function calcTotal() {
$stmt = $this->pdo->query("SELECT COUNT(*) FROM {$this->table}");
$this->totalRows = $stmt->fetchColumn();
$this->totalPages = ceil($this->totalRows / $this->perPage);
}
public function getData() {
$offset = ($this->page - 1) * $this->perPage;
$stmt = $this->pdo->prepare("SELECT * FROM {$this->table} LIMIT ?, ?");
$stmt->bindValue(1, $offset, PDO::PARAM_INT);
$stmt->bindValue(2, $this->perPage, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
public function render($showPages = 5) { /* 輸出導航 HTML */ }
}
類別化設計便於複用、測試與維護,配合 PDO 預處理語句杜絕 SQL 注入風險。