本文目录导读:

在 PHP 中设置搜索权重通常不是指 PHP 语言本身的配置,而是指在业务逻辑中实现搜索结果的排序算法,这主要取决于你使用的是关系型数据库(MySQL)、全文搜索引擎(Elasticsearch)还是纯 PHP 数组。
以下是三种最常见的实现方式,按推荐程度排序:
使用 MySQL(高级:全文索引 + 权重)
如果你用的是 MySQL 5.7+ 或 8.0,推荐使用内置的 FULLTEXT 索引,它支持自然语言模式,且可以通过 BOOLEAN MODE 配合 、、>(提高权重)等操作符。
场景: 搜索商品名称和描述,希望标题匹配的排前面。
<?php
$keyword = 'PHP 教程';
// 使用布尔模式,给“标题”字段增加权重
$sql = "SELECT
id,
title,
description,
// 计算相关度分数(自定义权重计算)
(CASE
WHEN title LIKE '%".$keyword."%' THEN 10
ELSE 0
END) +
(CASE
WHEN description LIKE '%".$keyword."%' THEN 5
ELSE 0
END) AS relevance_score
FROM articles
WHERE title LIKE '%".$keyword."%' OR description LIKE '%".$keyword."%'
ORDER BY relevance_score DESC, views DESC";
// 更高效的方案:使用 MySQL 原生的 MATCH AGAINST
$sql_native = "SELECT
id,
title,
// 给标题字段乘以2的权重(需要字段在FULLTEXT里)
(MATCH(title) AGAINST('".$keyword."') * 2 + MATCH(description) AGAINST('".$keyword."')) AS relevance
FROM articles
WHERE MATCH(title, description) AGAINST('".$keyword."' IN BOOLEAN MODE)
ORDER BY relevance DESC";
?>
注意:
MATCH...AGAINST性能最优,但需要在建表时加上FULLTEXT(title, description)索引。
使用 Elasticsearch(专业搜索)
如果你需要复杂的打分、同义词、拼音、分词,ES 是工业级标准,权重通过 boost 参数设置。
<?php
// 假设使用官方客户端
$params = [
'index' => 'articles',
'body' => [
'query' => [
'bool' => [
'should' => [
// 标题匹配,权重为 3(更关键)
[
'match' => [
'title' => [
'query' => 'PHP 教程',
'boost' => 3
]
]
],
// 标签匹配,权重为 2
[
'match' => [
'tags' => [
'query' => 'PHP',
'boost' => 2
]
]
],
// 内容匹配,权重为 1(最低)
[
'match' => [
'content' => [
'query' => '教程',
'boost' => 1
]
]
]
]
]
]
]
];
?>
纯 PHP 数组排序(轻量级)
如果数据量很小,且没有数据库,可以在内存中用 usort 实现加权排序。
场景: 从 API 获取数据后,在本地根据关键词加权排序。
<?php
$data = [
['title' => 'PHP入门教程', 'content' => '基础', 'tags' => ['PHP']],
['title' => 'Java高级', 'content' => 'PHP实战', 'tags' => ['Java']],
['title' => '实战PHP', 'content' => '进阶', 'tags' => ['PHP', 'MySQL']],
];
$keyword = 'PHP';
// 计算每个元素的权重
$scored = array_map(function ($item) use ($keyword) {
$score = 0;
// 权重分配:标题命中 +5,标签命中 +3,内容命中 +1
if (stripos($item['title'], $keyword) !== false) {
$score += 5;
}
if (in_array($keyword, $item['tags'])) {
$score += 3;
}
if (stripos($item['content'], $keyword) !== false) {
$score += 1;
}
// 加入原始数据
$item['_score'] = $score;
return $item;
}, $data);
// 按权重降序排序
usort($scored, function ($a, $b) {
return $b['_score'] - $a['_score'];
});
// 过滤掉0权重的结果
$results = array_filter($scored, function ($item) {
return $item['_score'] > 0;
});
print_r($results);
?>
数据库通用方案(MySQL + PHP 计算)
如果你没有全文索引,但需要灵活的权重控制,可以纯 SQL 计算,但注意性能。
SELECT *,
(CASE
WHEN title LIKE '%关键词%' THEN 10
WHEN tags LIKE '%关键词%' THEN 5
WHEN content LIKE '%关键词%' THEN 2
ELSE 0
END) AS weight
FROM posts
WHERE title LIKE '%关键词%' OR tags LIKE '%关键词%' OR content LIKE '%关键词%'
ORDER BY weight DESC, created_at DESC;
总结建议
- 数据 < 1万条:用 PHP 数组方案或 MySQL
LIKE+CASE WHEN,简单直接。 - 数据 1万~100万:用 MySQL
FULLTEXTBOOLEAN MODE,性能好。 - 数据 > 100万 或需中文分词/复杂排序:必须上 Elasticsearch(或 Sphinx),权重设置才有效果。
如果你告诉我具体的数据结构(表字段)和数据量,可以给你写一个更精确的 SQL 示例。