經驗交流

關於「資料分頁」

問題說明
 當資料量太大,全部顯示在同一頁面中「有礙觀瞻」時,我們需要進行分頁處理。

我的做法
 在資料分頁處理上,有三個主要步驟:
一、計算資料總筆數:
 您可以使用 SELECT COUNT(*) FROM table_name 的 SQL 語法,快速地自資料庫中取得資料的總筆數。
<?
01    // 接收前頁傳來的 $Page,以決定本頁顯示的資料
02    $now_Page = $Page;
03    if ( $now_Page == "" ) $now_Page = 0;

04    // 每頁顯示 5 筆
05    $show_num = 5;

06    // 本頁之起始指標
07    $record_begin = $now_Page * $show_num;

08    // 本頁實際顯示筆數
09    $record_show = $show_num;

10    // 計算資料總筆數
11    $sql = "select count(*) from friend ";
12    $rs_f = mysql_db_query($cfgDatabaseName, $sql, $link);
13    list($nTotal) = mysql_fetch_row($rs_f);

14    // 本頁之實際顯示筆數不可大於總筆數
15    if ( ( $record_begin + $record_show ) > $nTotal )
16      $record_show = $nTotal - $record_begin;
?>
 02 - 03 如果本頁有接收到 $Page 變數,即依其值顯示該頁;否則顯示第 0 頁。
 05 用 $show_num 變數來記錄每頁應顯示的資料筆數,日後若要改變每頁呈現數量的話,僅需異動此處即可。
 07 計算本頁應自哪一筆資料開始顯示。此即下一步驟會使用到的 offset
 09 原則上,本頁將顯示 $show_num 筆資料,但有可能在 15 - 16 之中進行調整。
 11 - 13 計算資料總筆數。這項數據主要用來決定本頁應顯示的資料筆數,同時也將決定是否出現「上一頁」與「下一頁」之連結。
 如果在此所得到的 $nTotal 不為 0 的話,那就需要將資料顯示出來了。倘若,沒任何資料該顯示的話,那麼第二、三步驟都不必執行了。
 15 - 16 在最後一頁中,應呈現的資料量可能比 $show_num 還少,因此,需調整實際顯示的筆數($record_show),此一結果將被應用在下一步驟的 rows

二、顯示本頁資料:
 每頁應顯示的資料均不盡相同,請使用 SELECT col1, col2, col3, ...... FROM table_name LIMIT offset, rows 語法,只從資料庫中取出本頁該顯示的部份。語法中的 offset 係用來指定自哪一筆紀錄開始讀取,rows 則是讀取的筆數;注意喔!紀錄的編號是從 0 開始的。
 假如每頁要顯示 5 筆資料,全部共有 13 筆,則第一頁應該是 LIMIT 0, 5(自第 0 筆起,取 5 筆),第二頁是 LIMIT 5, 5(自第 5 筆起,取 5 筆),第三頁則是 LIMIT 10, 3(自第 10 筆起,取 3 筆)。

三、決定是否出現「上一頁」與「下一頁」之連結:
 13 筆資料,每頁 5 筆,那得分 3 頁來顯示它們,您可以用 ceil 函數(無條件進入)來取得這個數字:$TotalPage = ceil( 總筆數/每頁筆數 )。
01    <table border=0 cellpadding=2 cellspacing=0 width=80%>
02      <tr>
03        <td align=right nowrap>
04          <form method="get" name="PageChange" action="X_3_demo.php">
05          <?
06          if ( $now_Page > 0 ) {?>
07            <a href="JavaScript:showPage(<?echo $now_Page-1;?>);">
08              <img src="media/arrow_left.gif" border=0 alt="上一頁"></a>
09          <?
10          }

11          // 計算總頁數
12          $PageTotal = ceil($nTotal/$show_num);?>

13          <font class="myFont_9G">
14          第 <?echo $now_Page+1;?> 頁,
15          共 <?echo $PageTotal;?> 頁 
16          ( <?echo $nTotal;?> 筆資料 )</font>
17          <?
18          if ( $PageTotal > ($now_Page + 1) ) {?>
19            <a href="JavaScript:showPage(<?echo $now_Page+1;?>);">
20              <img src="media/arrow_right.gif" border=0 alt="下一頁"></a>
21          <?
22          }?> 
23            <input type="hidden" name="Page" value="">
24            <select name="PageSelect" onChange="JavaScript:showPage(document.PageChange.PageSelect.selectedIndex - 1);">
25              <option value="">快速換頁
26            <?
27            for ( $b=1; $b<=$PageTotal; $b++ )
28              echo "<option value=" . $b . ">第 " . $b . " 頁";?>
29            </select>
30          </form>
31        </td>
32      </tr>
33    </table>
34    <script language="JavaScript">
35    function showPage(Page) {
36      document.PageChange.Page.value = Page;
37      document.PageChange.submit();
38    }
39    </script>
 04 使用 Form 來傳送換頁資訊。由於本範例程式之檔名為 X_3_demo.php,所以 action 要指向它;如果您的檔名與我不同,請修改 action 指向的位置。
 06 - 10 只要目前的頁次大於第 0 頁(對使用者而言是第 1 頁),就要出現「上一頁」的連結點。
 12 使用 ceil 函數來計算總頁次($PageTotal)。
 18 - 22 只要總頁次($PageTotal)大於「目前頁次加 1」時(在程式中,頁次的編號是從 0 開始的),就要出現「下一頁」的連結點。
 23 用來傳送「下一頁次」的元件。
 24 - 29 使用 select 元件來進行「快速換頁」。
 這裡需搭配 JavaScript 語法來執行,請見我們自定的函數:showPage( )(見 35 - 38)。當 select 元件的選項被改變時,會將使用者的選取結果(selectedIndex)傳給 showPage( )。
 selectedIndex 為什麼要減 1?

選單中的顯示值 selectedIndex 程式應對應的頁次
快速換頁 0 ---
第 1 頁 1 0
第 2 頁 2 1

 selectedIndex 正好比程式所需的頁次多了 1,所以必須先減去。
 為什要有「快速換頁」這個選項?因為 showPage( ) 函數將在 select 元件被改變時被自動呼叫;若無「快速換頁」的話,「第 1 頁」就是預設的選項,想去第 1 頁的使用者,不必改變 select 元件的選項,但也因此無法自動呼叫 showPage( ) 函數了。
 35 - 38 使用 JavaScript 自定一個函數。請注意!這個函數只能在 Client 端被瀏覽器使用,切莫在 Server 端的 PHP 程式中去呼叫它。

基本範例 基本範例原始碼

進階做法
 我在進階範例中加入了 Session 的用法,以便提供「排序」的功能,請您參考!
進階範例 進階範例原始碼
經驗交流