:::

6-3-6 加入分頁

一、安裝分頁物件

  1. 分頁功能不算難,但有點複雜,因此,建議直接用現成物件來實做即可
  2. 官網:https://github.com/jasongrimes/php-paginator
  3. 安裝 php-paginator 物件按 Ctrl+` 開啟終端機,並貼上以下指令執行之 : :
    composer require "jasongrimes/paginator:~1.0"

     

二、使用分頁物件

  1. 修改index.php,先 use 該物件
  2. 由於點擊分頁工具時,一定會傳一個頁數給檔案,如此才知道目前要顯示哪一頁的內容,我們暫且假定這個頁碼的變數叫做 $p
  3. 由於是外來的變數,所以我們可以用$_REQUEST來接收(實際上是$_GET ),所以一定要過濾,若沒有該變數,也要將頁碼預設值為1
    <?php
    use JasonGrimes\Paginator;
    require_once 'header.php';
    
    // 過濾外來變數
    $p = isset($_REQUEST['p']) ? (int) $_REQUEST['p'] : 1;

     

  4. 我們先修改 config.php,多一個「每頁顯示文章數」的設定,方便日後調整
    // 每頁顯示文章數
    define('_NEWS_PER_PAGE', 3);
    

     

  5. 接著繼續修改 index.php
    1. 首先要抓出文章總數 $total,分頁工具才能用它來計算出頁數
    2. config.php 取得每頁顯示文章數,並賦值給 $news_per_page(後續會比較好運算),除了分頁物件會用到,我們也要靠它計算出從資料庫的 LIMIT 語法要從哪裡開始($start)抓出幾筆資料
    3. 分頁物件必須給予文章總數 $total、每頁顯示文章數 $news_per_page、當前頁碼 $p、欲傳回的連結樣式,頁數用(:num)來取代
    4. 分別取得上一頁、下一頁、所有分頁的值後,通通加入到 $all_news 陣列中,以便讓樣板去產生分頁工具
    5. 要注意的是,本來取得所有文章內容是放到$all_news 陣列中,但現在$all_news 陣列中又有包含其他資料,所以,是必要做個區隔,因此,所有文章內容我們將之改為 $all_news['data'] 陣列中,以避免送到樣板要讀出文章時,也把分頁資料當成文章了。
  6. 完整修改語法如下:
    $all_news = [];
    // 根據條件計算文章總數 $total
    $sql = "SELECT count(*) FROM `articles` ORDER BY `date` DESC";
    $sth = $db->prepare($sql);
    $sth->execute();
    list($total) = $sth->fetch(PDO::FETCH_NUM);
    
    // 每頁顯示文章數
    $news_per_page = _NEWS_PER_PAGE;
    
    // 產生分頁內容
    $paginator = new Paginator($total, $news_per_page, $p, "index.php?p=(:num)");
    $all_news['next_pages'] = $paginator->getNextUrl(); // 上一頁網址
    $all_news['prev_pages'] = $paginator->getPrevUrl(); // 下一頁網址
    $all_news['pages'] = $paginator->getPages(); // 分頁工具所需資料
    
    // 計算從哪筆資料開始讀取
    $start = ($p - 1) * $news_per_page;
    
    // 根據計算結果來讀取資料
    $sql = "SELECT * FROM `articles` ORDER BY `date` DESC LIMIT ? , ?";
    $sth = $db->prepare($sql);
    $sth->execute([$start, $news_per_page]);
    
    while ($news = $sth->fetch(PDO::FETCH_ASSOC)) {
        ...略...
        
        $all_news['data'][] = $news;
    }
    
    1. LIMIT 0,10 :會抓出1~10的資料(第一頁)
      LIMIT 10,10 :會抓出11~20的資料(第二頁)
      所以,$start必須用現有頁碼-1,再乘上每頁文章數才是正確的起始值。

    2. getNextUrl()會得到下一頁的網址、getPrevUrl()會得到上一頁的網址,看起來像這樣,若無會傳回 null(不存在):
      'index.php?p=2'

      getNextPage()則會得到下一頁的頁數、getPrevPage()會得到上一頁的頁數,若無會傳回 null(不存在):

    3. getPages()會得到所有的分頁資料,看起來像這樣:
      <?php
      array(
          array('num' => 1, 'url' => 'index.php?p=1', 'isCurrent' => false),
          array('num' => 2, 'url' => 'index.php?p=2', 'isCurrent' => true),
          array('num' => 3, 'url' => 'index.php?p=3', 'isCurrent' => false),
      );
      

       

  7. 最後記得將分頁資訊也送到樣板
    // 將所有文章送至樣板
    $smarty->assign('all_news', $all_news);
    // 將分頁資訊送至樣板
    $smarty->assign('page_tool', $page_tool);
    $smarty->display('index.tpl');
    

     

三、在樣板檔加入分頁工具

  1. 我們可以利用 BootStrap5 的分頁元件來產生分頁工具:https://bootstrap5.hexschool.com/docs/5.0/components/pagination/#alignment
  2. 修改 news.tpl,加入分頁:
    <!-- 依序取出每篇文章 -->
    {foreach $all_news.data as $news}
      {include file='card.tpl'}
    {/foreach}
    
    <!-- 分頁工具 -->
    <nav aria-label="Page navigation example">
      <ul class="pagination justify-content-center">
        <li class="page-item {if !$all_news.prev_pages}disabled{/if}">
          <a class="page-link" href="{$all_news.prev_pages}">上一頁</a>
        </li>
        {foreach $all_news.pages as $page}
          <li class="page-item {if $page.isCurrent}active{/if}">
            <a class="page-link" href="{$page.url}">{$page.num}</a>
          </li>
        {/foreach}
        <li class="page-item {if !$all_news.next_pages}disabled{/if}">
          <a class="page-link" href="{$all_news.next_pages}">下一頁</a>
        </li>
      </ul>
    </nav>

     

    1. 在迴圈中,原本的 $all_news 要改成 $all_news['data']$all_news.data 才能讀到正確的文章資料。
    2.  !$all_news.prev_pages 是指當$all_news.prev_pages不存在(null)時,那就把上一頁的按鈕設成 disabled,讓使用者無法按。下一頁的部份也一樣道理。
    3. 最後看起來像這樣:

:::

書籍目錄

展開 | 闔起

https%3A%2F%2Fcampus-xoops.tn.edu.tw%2Fmodules%2Ftad_book3%2Fpage.php%3Ftbsn%3D52%26tbdsn%3D1837

計數器

今天: 4037403740374037
昨天: 5069506950695069
總計: 5134485513448551344855134485513448551344855134485