本文目录导读:

- 方案一:MySQL
LIKE查询(适合数据量 < 10万,临时或简单需求) - 方案二:Elasticsearch(强烈推荐,适合商业或大规模项目)
- 方案三:Meilisearch(轻量级替代方案,适合中小项目)
- 建议
- 额外注意事项
实现 PHP 项目的站内搜索功能,有简单粗暴和专业强大两种路径,具体取决于你的数据量、搜索需求(如是否需要分词、拼音、模糊匹配)和性能要求。
以下是三种主流方案的详细介绍与代码示例:
MySQL LIKE 查询(适合数据量 < 10万,临时或简单需求)
这是最直接的方式,利用 SQL 的 LIKE 或 REGEXP 进行模糊匹配。
优点:无需额外组件,开发快。
缺点:性能随数据量增长急剧下降,不支持中文分词,不支持搜索排名。
实现步骤:
- 前端表单:用户输入关键词。
- 后端 SQL:拼接
LIKE语句进行查询。 - 结果展示:返回匹配结果。
核心代码示例(PHP + MySQL):
<?php
$keyword = $_GET['q'] ?? '';
// 1. 安全过滤(防止SQL注入)
$keyword = trim($keyword);
$keyword = mysqli_real_escape_string($conn, $keyword);
// 2. 构建SQL(假设搜索文章标题和内容)
// 如果用户输入 "PHP教程",会匹配包含该词的记录
$sql = "SELECT * FROM articles
WHERE title LIKE '%$keyword%'
OR content LIKE '%$keyword%'
ORDER BY created_at DESC
LIMIT 20";
$result = mysqli_query($conn, $sql);
// ... 处理结果
?>
重要改进(性能优化):
如果必须用 LIKE,建议至少给要搜索的字段加上全文索引,配合 MATCH AGAINST 替代 LIKE(但仅限 MyISAM 或 InnoDB 5.6+ 引擎)。
ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title, content);
-- 查询语法变为:
SELECT * FROM articles
WHERE MATCH(title, content) AGAINST('PHP教程' IN BOOLEAN MODE);
MATCH AGAINST 性能远高于 LIKE,且支持自然语言搜索和布尔搜索,适合中等规模数据。
Elasticsearch(强烈推荐,适合商业或大规模项目)
对于数据量大(10万+)、需要分词、拼音搜索、智能纠错、高亮、排序(按相关性)的场景,Elasticsearch(ES)是业界标准。
优点:分布式、高可用、分词准确、搜索快、功能强。
缺点:需要独立部署 Java 服务,运维成本稍高。
实现步骤:
- 部署 ES(可用 Docker 安装:
docker run -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.x)。 - 安装 PHP 客户端(Composer):
composer require elasticsearch/elasticsearch - 索引数据:将数据库内容同步到 ES 索引。
- 搜索查询:使用
match或multi_match查询。
核心代码示例(PHP + Elasticsearch):
创建并索引数据:
<?php
require_once 'vendor/autoload.php';
use Elastic\Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()
->setHosts(['localhost:9200'])
->build();
// 1. 创建索引并配置中文分词器(需要安装 IK 分词器插件)
$params = [
'index' => 'articles',
'body' => [
'settings' => [
'analysis' => [
'analyzer' => 'ik_smart' // 使用IK中文分词
]
],
'mappings' => [
'properties' => [
'title' => ['type' => 'text', 'analyzer' => 'ik_max_word'],
'content' => ['type' => 'text', 'analyzer' => 'ik_max_word'],
]
]
]
];
$client->indices()->create($params);
// 2. 索引一条文章
$article = [
'index' => 'articles',
'id' => 1,
'body' => [
'title' => 'PHP项目怎样实现站内搜索功能',
'content' => '本文介绍了使用Elasticsearch实现站内搜索...'
]
];
$client->index($article);
执行搜索:
<?php
// 接收前端关键词
$keyword = $_GET['q'] ?? '';
// 执行搜索
$params = [
'index' => 'articles',
'body' => [
'query' => [
'multi_match' => [
'query' => $keyword,
'fields' => ['title^3', 'content'], // title权重更高
'type' => 'best_fields'
]
],
'highlight' => [
'fields' => [
'title' => new \stdClass(),
'content' => new \stdClass()
]
]
]
];
$response = $client->search($params);
// 处理结果
foreach ($response['hits']['hits'] as $hit) {
$highlight = $hit['highlight'];
echo '<p>标题: ' . $highlight['title'][0] . '</p>';
echo '<p> ' . $highlight['content'][0] . '</p>';
}
Meilisearch(轻量级替代方案,适合中小项目)
Meilisearch 是一个更轻、更易用的 Rust 语言编写的搜索引擎,开箱即用,支持中文分词。
优点:安装简单(单文件二进制),无需配置分词(自动支持中文),响应快。
缺点:功能不如 ES 强大。
实现步骤:
- 安装 Meilisearch:下载二进制文件运行。
- 安装 PHP 客户端:
composer require meilisearch/meilisearch-php - 数据处理与搜索。
代码示例:
<?php
require_once 'vendor/autoload.php';
use Meilisearch\Client;
$client = new Client('http://localhost:7700', 'MASTER_KEY');
// 1. 添加文档
$documents = [
['id' => 1, 'title' => 'PHP教程', 'content' => '深入学习PHP编程...'],
['id' => 2, 'title' => 'Laravel框架', 'content' => 'Laravel入门与实践']
];
$client->index('articles')->addDocuments($documents);
// 2. 搜索
$keyword = 'PHP教程';
$results = $client->index('articles')->search($keyword, [
'attributesToHighlight' => ['title', 'content']
]);
foreach ($results->getHits() as $hit) {
echo $hit['title'] . '<br>';
}
| 方案 | 适合场景 | 性能 | 中文分词 | 运维成本 | 相关性排序 |
|---|---|---|---|---|---|
| MySQL LIKE | 极少量数据,原型验证 | 低 | 无 | 无 | 差 |
| MySQL FULLTEXT | 10万以下,中等需求 | 中 | 有限 | 无 | 一般 |
| Elasticsearch | 复杂搜索、大数据量、商业级 | 高 | 优秀 | 较高 | 优秀 |
| Meilisearch | 中小项目、快速集成 | 高 | 自动支持 | 低 | 好 |
建议
- 如果你的项目是博客、公司官网(文章数 < 1万):直接用 MySQL FULLTEXT MATCH AGAINST 即可,开发最快,无需额外服务器。
- 如果是电商网站、内容管理系统、论坛(10万+数据,需要拼音、纠错、高亮):优先选 Elasticsearch,虽然重一点,但长期收益最大。
- 如果你想在 5 分钟内跑起来一个不错的搜索:试试 Meilisearch,非常省心。
额外注意事项
- 中文分词是核心:对于中文搜索,
LIKE无法匹配“PHP项目”和“PHP 项目”(有空格),ES 或 Meilisearch 会自动处理。 - 搜索结果安全:注意权限控制,不要搜索到未发布的草稿或敏感内容。
- 增量同步:如果使用 ES/Meilisearch,需要定时同步数据库变更到搜索引擎(如通过队列任务或数据库 binlog 监听)。