本文目录导读:

在PHP项目中实现模糊搜索,常见的方法有以下几种:
使用SQL LIKE 语句(最基础)
MySQL示例
<?php
$search = $_GET['search'] ?? '';
$keyword = "%{$search}%";
// 使用预处理语句防止SQL注入
$stmt = $pdo->prepare("SELECT * FROM products
WHERE name LIKE :keyword
OR description LIKE :keyword2");
$stmt->execute([
':keyword' => $keyword,
':keyword2' => $keyword
]);
$results = $stmt->fetchAll();
?>
MySQL全文搜索(性能更好)
先创建全文索引
ALTER TABLE products ADD FULLTEXT INDEX ft_index (name, description);
PHP代码
<?php
$search = $_GET['search'] ?? '';
// 自然语言模式
$stmt = $pdo->prepare("SELECT *,
MATCH(name, description) AGAINST(:keyword) AS relevance
FROM products
WHERE MATCH(name, description) AGAINST(:keyword IN NATURAL LANGUAGE MODE)
ORDER BY relevance DESC");
$stmt->execute([':keyword' => $search]);
$results = $stmt->fetchAll();
?>
使用搜索引擎(高级方案)
Elasticsearch示例
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->build();
$params = [
'index' => 'products',
'body' => [
'query' => [
'multi_match' => [
'query' => $_GET['search'],
'fields' => ['name^3', 'description'] // name字段权重更高
]
]
]
];
$response = $client->search($params);
$results = $response['hits']['hits'];
?>
完整示例:前后端分离的模糊搜索
后端 (search.php)
<?php
header('Content-Type: application/json');
try {
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'root', '');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$search = $_GET['q'] ?? '';
if (empty($search)) {
echo json_encode(['status' => 'error', 'message' => '请输入搜索关键词']);
exit;
}
// 防止SQL注入
$keyword = '%' . $search . '%';
$stmt = $pdo->prepare("SELECT id, name, description, price
FROM products
WHERE name LIKE :keyword
OR description LIKE :keyword
LIMIT 20");
$stmt->execute([':keyword' => $keyword]);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'status' => 'success',
'data' => $results,
'total' => count($results)
]);
} catch (PDOException $e) {
echo json_encode(['status' => 'error', 'message' => '数据库错误']);
}
?>
前端 (search.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">模糊搜索示例</title>
<style>
#searchResults { margin-top: 20px; }
.result-item { padding: 10px; border-bottom: 1px solid #eee; }
</style>
</head>
<body>
<input type="text" id="searchInput" placeholder="输入搜索关键词...">
<div id="searchResults"></div>
<script>
const searchInput = document.getElementById('searchInput');
const resultsDiv = document.getElementById('searchResults');
let timeoutId;
searchInput.addEventListener('input', function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => performSearch(this.value), 300);
});
function performSearch(query) {
if (query.length < 2) {
resultsDiv.innerHTML = '';
return;
}
fetch(`search.php?q=${encodeURIComponent(query)}`)
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
displayResults(data.data);
} else {
resultsDiv.innerHTML = `<p>${data.message}</p>`;
}
})
.catch(error => {
resultsDiv.innerHTML = '<p>搜索出错,请重试</p>';
});
}
function displayResults(results) {
if (results.length === 0) {
resultsDiv.innerHTML = '<p>未找到相关结果</p>';
return;
}
let html = '';
results.forEach(item => {
html += `
<div class="result-item">
<h3>${highlightText(item.name)}</h3>
<p>${highlightText(item.description)}</p>
<p>价格: ¥${item.price}</p>
</div>
`;
});
resultsDiv.innerHTML = html;
}
// 高亮搜索关键词
function highlightText(text) {
const keyword = searchInput.value;
if (!keyword) return text;
const regex = new RegExp(`(${keyword})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
</script>
</body>
</html>
性能优化建议
数据库层面
-- 添加索引优化LIKE查询 CREATE INDEX idx_name ON products(name); -- 对于前缀模糊搜索有效 -- 避免以%开头的LIKE查询 -- 使用全文索引 ALTER TABLE products ADD FULLTEXT INDEX ft_search (name, description);
PHP层面
// 1. 限制搜索长度
$search = substr($search, 0, 50);
// 2. 清理特殊字符
$search = preg_replace('/[^\p{L}\p{N}\s]/u', '', $search);
// 3. 缓存搜索结果
$cacheKey = 'search_' . md5($search);
$cached = apcu_fetch($cacheKey);
if ($cached !== false) {
return $cached;
}
// ... 执行查询
apcu_store($cacheKey, $results, 300); // 缓存5分钟
选择建议
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| LIKE | 小数据量(<1万条) | 简单易用 | 性能差,不支持中文分词 |
| 全文索引 | 中等数据量 | 性能较好,支持中文 | 配置复杂 |
| Elasticsearch | 大数据量,复杂搜索 | 功能强大,支持分词 | 需要额外服务 |
| Sphinx | 全文搜索需求 | 性能优异 | 配置维护复杂 |
选择哪种方案取决于你的数据量、搜索复杂度和性能要求,对于大多数中小型项目,MySQL全文搜索已经足够。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播