新聞列表、文章列表等常見場景需支援分頁。本範例示範如何在 PHP 中連接 Microsoft SQL Server,計算總頁數、處理當前頁碼、執行分頁查詢並產生分頁導航列。
<?php
// config.php
$local = 'localhost'; // MSSQL 主機
$user = 'sa'; // 登入帳號
$pass = 'password'; // 密碼
$name = 'news_db'; // 資料庫名稱
$userperpage = 10; // 每頁筆數
?>
<?php
require "config.php";
// 1. 連接資料庫(現代建議使用 PDO 或 sqlsrv 驅動)
$conn = mssql_connect($local, $user, $pass) or die("連線失敗");
mssql_select_db($name, $conn) or die("選擇資料庫失敗");
// 2. 取得並驗證頁碼
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
// 3. 查詢總筆數
$total_result = mssql_query("SELECT COUNT(*) AS total FROM news", $conn);
$total_row = mssql_fetch_assoc($total_result);
$total_records = $total_row['total'];
// 4. 計算總頁數
$total_pages = ceil($total_records / $userperpage);
if ($page > $total_pages) $page = $total_pages;
// 5. 計算 OFFSET(MSSQL 2000/2005 使用 TOP + 子查詢或 ID 篩選)
$offset = ($page - 1) * $userperpage;
// 6. 分頁查詢(此處示範簡單法:先取所有 ID 再篩選,大量資料建議用 ROW_NUMBER())
// 現代 MSSQL (2012+) 可用:SELECT * FROM news ORDER BY date DESC OFFSET $offset ROWS FETCH NEXT $userperpage ROWS ONLY
$query = "SELECT * FROM news ORDER BY date DESC";
$result = mssql_query($query, $conn);
// 7. 移動指標到起始位置
mssql_data_seek($result, $offset);
// 8. 讀取當頁資料
echo "<table border='0' width='100%' cellspacing='0' cellpadding='0'>";
echo "<tr bgcolor='#B5C6B0'>
<th width='52%'>新聞標題</th>
<th width='14%'>發表日期</th>
<th width='19%'>發表部門</th>
<th width='7%'>閱讀</th>
<th width='8%'>圖片</th>
</tr>";
$count = 0;
while ($row = mssql_fetch_assoc($result)) {
if ($count >= $userperpage) break;
$date_str = date("Y-m-d", $row['date']); // 假設 date 欄位為 Unix timestamp
$has_photo = (!empty($row['photo']) && file_exists($row['photo'])) ? '<img src="picture.gif">' : '';
echo "<tr bgcolor='#F3F3F3'>";
echo "<td><a href='readnews.php?id={$row['date']}' target='_blank'>{$row['title']}</a></td>";
echo "<td align='center'>$date_str</td>";
echo "<td align='center'>{$row['type']}</td>";
echo "<td align='center'>{$row['click']}</td>";
echo "<td align='center'>$has_photo</td>";
echo "</tr>";
$count++;
}
echo "</table>";
// 9. 產生分頁導航
echo "<div align='center'>";
if ($page > 1) {
echo "<a href='?page=1'>首頁</a> ";
echo "<a href='?page=" . ($page - 1) . "'><font color='red'>上一頁</font></a> ";
}
for ($i = 1; $i <= $total_pages; $i++) {
if ($i == $page) {
echo "<strong>[$i]</strong> ";
} else {
echo "<a href='?page=$i'>$i</a> ";
}
}
if ($page < $total_pages) {
echo "<a href='?page=" . ($page + 1) . "'><font color='red'>下一頁</font></a> ";
echo "<a href='?page=$total_pages'>尾頁</a> ";
}
echo "</div>";
mssql_free_result($result);
mssql_close($conn);
?>
| 函式 | 用途 |
|---|---|
mssql_connect() | 建立 MSSQL 連線(已移除於 PHP 7+,請改用 sqlsrv_connect() 或 PDO) |
mssql_query() | 執行 SQL 查詢 |
mssql_fetch_assoc() | 取得關聯陣列結果 |
mssql_data_seek() | 移動結果集指標到指定行(實現分頁核心) |
mssql_num_rows() | 取得結果集總行數 |
ceil() | 無條件進位,計算總頁數 |
mssql_data_seek 掃描大量行:資料量大時極慢。改用 ROW_NUMBER() 視窗函數(MSSQL 2005+)或 OFFSET/FETCH(2012+)。date 欄位建立非叢集索引支援 ORDER BY date DESC。COUNT(*) 查詢。<?php
$dsn = "sqlsrv:Server=$local;Database=$name";
$pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 10;
$offset = ($page - 1) * $perPage;
// 總筆數
$total = $pdo->query("SELECT COUNT(*) FROM news")->fetchColumn();
$totalPages = ceil($total / $perPage);
// 分頁查詢
$stmt = $pdo->prepare("
SELECT * FROM news
ORDER BY date DESC
OFFSET :offset ROWS FETCH NEXT :perPage ROWS ONLY
");
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->bindValue(':perPage', $perPage, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// ... 輸出迴圈與分頁導航同前 ...
?>