後台管理系統常見需求:支援按「作者」「標題」「關鍵詞」三個欄位模糊搜索,並可單獨或組合使用。本文展示從參數接收、SQL 動態構建、防注入處理到模板渲染的完整鏈路。
<?php
// search.php - 搜索處理入口
require_once 'comm.php'; // $db, $tpl
// 1. 參數接收與清洗
$flag = isset($_POST['flag']) ? (int)$_POST['flag'] : -1; // 1=作者 2=標題 3=關鍵詞
$keyword = isset($_POST['keyword']) ? trim($_POST['keyword']) : '';
// 2. 動態構建 WHERE 子句
$where = 'WHERE 1=1 '; // 基礎條件,便於後續 AND 拼接
$params = [];
$types = '';
if ($keyword !== '' && $flag !== -1) {
$like = "%{$keyword}%"; // 預處理綁定時不含 %,這裡為演示拼接寫法
switch ($flag) {
case 1:
$where .= "AND author LIKE ? ";
$params[] = $like;
$types .= 's';
break;
case 2:
$where .= "AND title LIKE ? ";
$params[] = $like;
$types .= 's';
break;
case 3:
$where .= "AND keyword LIKE ? ";
$params[] = $like;
$types .= 's';
break;
}
}
// 3. 執行查詢(預處理防注入)
$sql = "SELECT * FROM article {$where} ORDER BY id DESC";
$stmt = $db->prepare($sql);
if ($params) {
$stmt->bind_param($types, ...$params);
}
$stmt->execute();
$result = $stmt->get_result();
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
$stmt->close();
// 4. 模板賦值輸出
$tpl->assign('soso', $data); // 搜索結果集
$tpl->assign('appname', '信息示例'); // 頁面標題
$tpl->display('index/up.tpl'); // 渲染模板
WHERE 1=1?避免首個條件需判斷是否加 WHERE 還是 AND,統一用 AND 拼接,代碼更簡潔,SQL 解析器會自動優化掉常量條件。
原代碼直接拼接 $sosoval 入 SQL,極度危險。正確做法:
// 錯誤示範
$sql = "SELECT * FROM article WHERE title LIKE '%{$keyword}%'";
// 正確:預處理 + 參數綁定
$stmt = $db->prepare("SELECT * FROM article WHERE title LIKE ?");
$like = "%{$keyword}%";
$stmt->bind_param('s', $like);
若需「標題或作者或關鍵詞」匹配:
$where = 'WHERE 1=1 ';
$params = [];
$types = '';
if ($keyword !== '') {
$like = "%{$keyword}%";
$where .= "AND (title LIKE ? OR author LIKE ? OR keyword LIKE ?) ";
$params = [$like, $like, $like];
$types = 'sss';
}
<?php
// 獲取總數(用於分頁)
$countSql = "SELECT COUNT(*) FROM article {$where}";
$countStmt = $db->prepare($countSql);
if ($params) $countStmt->bind_param($types, ...$params);
$countStmt->execute();
$total = $countStmt->get_result()->fetch_row()[0];
// 分頁參數
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = 20;
$offset = ($page - 1) * $perPage;
// 查詢當前頁數據
$sql = "SELECT * FROM article {$where} ORDER BY id DESC LIMIT ?, ?";
$params[] = $offset;
$params[] = $perPage;
$types .= 'ii';
// ...執行查詢
// 模板額外賦值分頁信息
$tpl->assign('pagination', [
'total' => $total,
'page' => $page,
'perPage' => $perPage,
'totalPage' => ceil($total / $perPage),
'keyword' => $keyword,
'flag' => $flag,
]);
index/search_form.tpl<form method="post" action="search.php" class="search-form">
<select name="flag">
<option value="-1">請選擇搜索範圍</option>
<option value="1">作者</option>
<option value="2">標題</option>
<option value="3">關鍵詞</option>
</select>
<input type="text" name="keyword" placeholder="輸入搜索關鍵詞" value="{$keyword|escape}">
<button type="submit">搜索</button>
</form>
CASE WHEN 或 ES 評分htmlspecialchars 轉義動態搜索的核心在於條件組裝邏輯清晰、參數化查詢防注入、分頁與搜索狀態保持。本文代碼採用預處理語句、結構化 WHERE 構建、模板分離,具備良好的可維護性與安全性。隨業務增長,適時引入專業搜索引擎可獲得數量級的性能與體驗提升。