PHP站内搜索功能的核心是通过用户输入的关键词,在网站对应的数据库表中匹配相关内容,再将结果返回给用户。实现过程需要兼顾功能可用性和查询效率,避免因为搜索逻辑不合理导致网站响应变慢。

基础实现步骤
1. 数据库表设计
首先需要准备存储内容的表,以文章表为例,基础结构如下:
CREATE TABLE `article` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL COMMENT '文章标题', `content` text NOT NULL COMMENT '文章内容', `create_time` datetime NOT NULL COMMENT '发布时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 搜索接口编写
接收用户输入的关键词,拼接查询语句查询数据,基础实现代码如下:
<?php
// 数据库配置
$host = '127.0.0.1';
$user = 'root';
$pass = '123456';
$dbname = 'test';
// 连接数据库
$conn = new mysqli($host, $user, $pass, $dbname);
if ($conn->connect_error) {
die("数据库连接失败: " . $conn->connect_error);
}
// 接收搜索关键词,过滤特殊字符
$keyword = isset($_GET['keyword']) ? trim($conn->real_escape_string($_GET['keyword'])) : '';
if (empty($keyword)) {
echo "请输入搜索关键词";
exit;
}
// 基础模糊查询
$sql = "SELECT id, title, create_time FROM article WHERE title LIKE '%$keyword%' OR content LIKE '%$keyword%' LIMIT 0, 10";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "标题: " . $row['title'] . " 发布时间: " . $row['create_time'] . "<br/>";
}
} else {
echo "未找到相关内容";
}
$conn->close();
?>常见问题与优化方法
1. 查询效率优化
上面的模糊查询在数据量大的时候会全表扫描,速度很慢,可以通过给搜索字段添加全文索引优化:
-- 给title和content字段添加全文索引
ALTER TABLE article ADD FULLTEXT INDEX ft_title_content (title, content);
-- 使用全文索引查询
SELECT id, title, create_time FROM article WHERE MATCH(title, content) AGAINST('$keyword' IN NATURAL LANGUAGE MODE) LIMIT 0, 10;注意全文索引对中文的支持需要MySQL版本在5.7以上,且表的字符集为utf8mb4,同时可以调整ft_min_word_len参数,让短关键词也能被匹配到。
2. 搜索结果分页
当搜索结果较多时,需要添加分页功能,避免一次性返回大量数据:
<?php
// 每页显示条数
$pageSize = 10;
// 当前页码,默认第一页
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
// 计算偏移量
$offset = ($page - 1) * $pageSize;
// 查询总条数
$countSql = "SELECT COUNT(*) as total FROM article WHERE MATCH(title, content) AGAINST('$keyword' IN NATURAL LANGUAGE MODE)";
$countRes = $conn->query($countSql)->fetch_assoc();
$total = $countRes['total'];
$totalPage = ceil($total / $pageSize);
// 查询当前页数据
$sql = "SELECT id, title, create_time FROM article WHERE MATCH(title, content) AGAINST('$keyword' IN NATURAL LANGUAGE MODE) LIMIT $offset, $pageSize";
$result = $conn->query($sql);
// 输出结果和分页链接
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "标题: " . $row['title'] . " 发布时间: " . $row['create_time'] . "<br/>";
}
// 分页导航
echo "共" . $total . "条结果 第" . $page . "页/共" . $totalPage . "页<br/>";
if ($page > 1) {
echo "<a href='?keyword=" . $keyword . "&page=" . ($page-1) . "'>上一页</a> ";
}
if ($page < $totalPage) {
echo "<a href='?keyword=" . $keyword . "&page=" . ($page+1) . "'>下一页</a>";
}
}
?>3. 安全与体验优化
- 过滤特殊字符:使用
real_escape_string或者预处理语句避免SQL注入,上面的示例已经做了基础过滤,生产环境建议使用PDO预处理 - 关键词高亮:可以在返回结果的时候,把匹配到的关键词用
em标签包裹,提升用户阅读体验 - 空结果处理:当没有搜索到结果时,可以推荐热门内容或者提示用户更换关键词
进阶优化方向
如果网站内容量非常大,基础的MySQL全文索引可能无法满足需求,可以考虑引入专业的搜索引擎比如Elasticsearch,通过PHP调用Elasticsearch的接口实现更复杂的搜索功能,比如分词搜索、权重排序、搜索历史记录等,进一步提升搜索的准确性和响应速度。