:::
6-3 讓搜尋框有作用
- 先改寫
templates/index_nav.tpl搜尋框表單部份:- 先幫
<form>加上action="index.php"屬性,才知道關鍵字到要送到哪裡處理。 - 幫
<input>加上name="keyword",如此,才能接收到使用者填的關鍵字變數$_GET['keyword'] - 當
isset($smarty.get.keyword)存在時,才幫<input>加上value="{$smarty.get.keyword}",如此,送出後,搜尋框會保留輸入的關鍵字方便使用者修改 - 由於沒有特別設定
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>
- 先幫
- 在
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']) : ''; - 在流程的
index()函式加入$keyword參數// 預設為文章列表 default: list($all_news, $paginator) = index($category, $keyword, $perPage); $smarty->assign('all_news', $all_news); $smarty->assign('paginator', $paginator); break; - 接著是取得所有文章的函式
// 列出所有文章 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]; }- 新增參數
$keyword,若有預設值的話,表示呼叫時不用輸入該參數也沒關係。 - 接著判斷有無
$keyword,若有,就用 SQL 的like語法,搭配%萬用字元,分別找出資料表中title、content、author這幾個欄位,和關鍵字相符的資料。 - 要注意的是,
%萬用字元不可放在預備語句中,而是要放到變數綁定裡。
- 新增參數
- 如此,我們就完成關鍵字搜尋囉!

6-2 該分類沒有文章的處理