:::

6-3 讓搜尋框有作用

  1. 先改寫 templates/index_nav.tpl 搜尋框表單部份:
    1. 先幫 <form> 加上 action="index.php" 屬性,才知道關鍵字到要送到哪裡處理。
    2. <input> 加上 name="keyword",如此,才能接收到使用者填的關鍵字變數 $_GET['keyword']
    3. isset($smarty.get.keyword) 存在時,才幫 <input> 加上 value="{$smarty.get.keyword}",如此,送出後,搜尋框會保留輸入的關鍵字方便使用者修改
    4. 由於沒有特別設定 method,所以,預設就是以 get 的方式傳遞變數(搜尋會建議用 get,其餘會建議用 post
      <form action="index.php" class="d-flex my-2 my-lg-0">
          <input class="form-control me-sm-2" type="text" placeholder="搜尋文章" name="keyword" {if isset($smarty.get.keyword)}value="{$smarty.get.keyword}"{/if}>
          <button class="btn btn-warning my-2 my-sm-0 text-nowrap" type="submit">搜尋</button>
      </form>

       

  2. index.php 上方加入關鍵字變數的過濾
    // 變數過濾
    $id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : 0;
    $op = isset($_REQUEST['op']) ? htmlspecialchars($_REQUEST['op']) : 'index';
    $category = isset($_REQUEST['category']) ? (int) $_REQUEST['category'] : 0;
    $keyword = isset($_REQUEST['keyword']) ? htmlspecialchars($_REQUEST['keyword']) : '';

     

  3. 在流程的 index() 函式加入 $keyword 參數
    // 預設為文章列表
    default:
        list($all_news, $paginator) = index($category, $keyword, $perPage);
        $smarty->assign('all_news', $all_news);
        $smarty->assign('paginator', $paginator);
        break;
  4. 接著是取得所有文章的函式
    // 列出所有文章
    function index($category = 0, $keyword = '', $perPage = 10)
    {
        global $pdo;
        // 計算總資料數
        try {
            if ($keyword) {
                $stmt = $pdo->prepare('SELECT count(*) FROM `news` WHERE `title` LIKE ? OR `content` LIKE ? OR `author` LIKE ?');
                $stmt->execute(["%$keyword%", "%$keyword%", "%$keyword%"]);
            } elseif ($category) {
                $stmt = $pdo->prepare('SELECT count(*) FROM `news` WHERE `category`=?');
                $stmt->execute([$category]);
            } else {
                $stmt = $pdo->prepare('SELECT count(*) FROM `news`');
                $stmt->execute();
            }
            list($totalCount) = $stmt->fetch(PDO::FETCH_NUM);
            // 產生分頁物件
            $pagination = new Pagination(['totalCount' => $totalCount, 'perPage' => $perPage]);
            // 產生分頁工具列
            ob_start();
            Paginator::widget(['pagination' => $pagination]);
            $paginator = ob_get_clean();
        } catch (PDOException $e) {
            die("計算總資料數失敗:" . $e->getMessage());
        }
    
        try {
            if ($keyword) {
                $stmt = $pdo->prepare('SELECT * FROM `news` WHERE `title` LIKE ? OR `content` LIKE ? OR `author` LIKE ? ORDER BY `date` DESC LIMIT ?, ?');
                $stmt->execute(["%$keyword%", "%$keyword%", "%$keyword%", $pagination->offset, $pagination->limit]);
            } elseif ($category) {
                $stmt = $pdo->prepare('SELECT * FROM `news` WHERE `category`=? ORDER BY `date` DESC LIMIT ?, ?');
                $stmt->execute([$category, $pagination->offset, $pagination->limit]);
            } else {
                $stmt = $pdo->prepare('SELECT * FROM `news` ORDER BY `date` DESC LIMIT ?, ?');
                $stmt->execute([$pagination->offset, $pagination->limit]);
            }
            $all_news = [];
            $news = $stmt->fetchAll();
            foreach ($news as $row) {
                $media = $row['media'];
                unset($row['media']);
                $row = array_map('htmlspecialchars', $row);
                $row['files'] = json_decode($media, true);
                $all_news[] = $row;
            }
    
        } catch (PDOException $e) {
            echo "資料庫連接錯誤:" . $e->getMessage();
        }
        return [$all_news, $paginator];
    }

     

    1. 新增參數 $keyword,若有預設值的話,表示呼叫時不用輸入該參數也沒關係。
    2. 接著判斷有無 $keyword,若有,就用 SQL 的 like 語法,搭配 % 萬用字元,分別找出資料表中 titlecontentauthor 這幾個欄位,和關鍵字相符的資料。
    3. 要注意的是,% 萬用字元不可放在預備語句中,而是要放到變數綁定裡。
  5. 如此,我們就完成關鍵字搜尋囉!

:::

書籍目錄

展開 | 闔起

快速登入


https%3A%2F%2Fcampus-xoops.tn.edu.tw%2Fmodules%2Ftad_book3%2Fpage.php%3Ftbdsn%3D1828%26tbsn%3D52

計數器

今天: 5059505950595059
昨天: 2489248924892489
總計: 8027041802704180270418027041802704180270418027041