首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 多條件動態搜索實現:SQL 構建與模板賦值完整流程

     編輯:PHP 相關知識

需求場景

後台管理系統常見需求:支援按「作者」「標題」「關鍵詞」三個欄位模糊搜索,並可單獨或組合使用。本文展示從參數接收、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');        // 渲染模板

關鍵技術點解析

1. 為什麼用 WHERE 1=1?

避免首個條件需判斷是否加 WHERE 還是 AND,統一用 AND 拼接,代碼更簡潔,SQL 解析器會自動優化掉常量條件。

2. 預處理語句防 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);

3. 擴展:多欄位組合搜索(OR 邏輯)

若需「標題或作者或關鍵詞」匹配:

$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';
}

4. 分頁整合

<?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,
]);

5. 前端表單模板 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>

進階優化方向

  1. 全文檢索引擎: 數據量超 10 萬建議接入 Elasticsearch / Meilisearch / Sphinx
  2. 搜索建議: AJAX 實時提示,基於 Redis 熱門詞或 Trie 樹
  3. 搜索日誌分析: 記錄無結果關鍵詞,指導內容補充
  4. 權重排序: 標題匹配 > 關鍵詞匹配 > 內容匹配,使用 CASE WHEN 或 ES 評分
  5. 緩存熱門查詢: Redis 緩存前 10 頁結果,TTL 5-10 分鐘

安全檢查清單

  • [ ] 所有用戶輸入經預處理綁定,禁止拼接
  • [ ] 關鍵詞長度限制(如 1-50 字符)
  • [ ] 限制單用戶搜索頻率(防爬蟲/濫用)
  • [ ] 敏感字過濾(可選)
  • [ ] 輸出到模板時經 htmlspecialchars 轉義

總結

動態搜索的核心在於條件組裝邏輯清晰、參數化查詢防注入、分頁與搜索狀態保持。本文代碼採用預處理語句、結構化 WHERE 構建、模板分離,具備良好的可維護性與安全性。隨業務增長,適時引入專業搜索引擎可獲得數量級的性能與體驗提升。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved