🗣 Wd提问: php分页sphinx
🤖 Ai回答: 在 PHP 里用 Sphinx 做分页,核心思路就是:
1、用 SphinxClient 向 Sphinx 发起查询,只取“当前页”需要的那几条记录;
2、把 Sphinx 返回的 `matches` 里的文档 id 拿出来,再去 MySQL 里把完整字段补齐;
3、根据 Sphinx 返回的 `total_found` 计算总页数、生成翻页 HTML。
下面给一段最常用、最简洁的完整示例,可直接拷到项目里改改就能跑。
一、安装/确认环境
Sphinx 服务已启动(searchd 进程在跑)。
PHP 装了 `sphinx` 扩展(`pecl install sphinx`),或者直接用纯 PHP 的 SphinxAPI 文件(`sphinxapi.php`)。
二、Sphinx 配置文件(sphinx.conf)片段
source mysrc
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass = 123456
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query = \
SELECT id, title, content, UNIX_TIMESTAMP(created) AS created \
FROM article
sql_attr_uint = created
}
index myidx
{
source = mysrc
path = /usr/local/sphinx/var/data/myidx
morphology = stem_en
charset_table = 0..9, A..Z-a..z, _, a..z, U+410..U+42F-U+430..U+44F, U+430..U+44F
}
三、PHP 代码(search.php)
php
<?php
require_once 'sphinxapi.php'; // 如果用 PECL 扩展可省掉
// 1、接收参数
$keyword = isset($_GET['q']) ? trim($_GET['q']) : '';
$page = isset($_GET['page']) ? max(1, intval($_GET['page'])) : 1;
$pageSize = 10; // 每页条数
// 2、连 Sphinx
$cl = new SphinxClient();
$cl-SetServer('127.0.0.1', 9312);
$cl-SetConnectTimeout(3);
$cl-SetArrayResult(true);
$cl-SetMatchMode(SPH_MATCH_EXTENDED2);
// 3、分页核心
$offset = ($page 1) * $pageSize;
$cl-SetLimits($offset, $pageSize); // 只取当前页 id
$cl-SetSortMode(SPH_SORT_RELEVANCE); // 也可 SPH_SORT_ATTR_DESC
// 4、查询
$res = $cl-Query($keyword, 'myidx');
if ($res === false) {
exit('Sphinx 查询失败: ' 、$cl-GetLastError());
}
// 5、总记录数/总页数
$totalFound = isset($res['total_found']) ? $res['total_found'] : 0;
$totalPages = $totalFound ? ceil($totalFound / $pageSize) : 0;
// 6、如果结果为空
if (empty($res['matches'])) {
echo '没有结果';
exit;
}
// 7、用 id 去 MySQL 取完整数据
$idList = array_column($res['matches'], 'id');
$idStr = implode(',', $idList);
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'root', '123456');
$sql = SELECT id,title,content,created FROM article WHERE id IN ($idStr) ORDER BY FIELD(id,$idStr);
$stmt = $pdo-query($sql);
$rows = $stmt-fetchAll(PDO::FETCH_ASSOC);
// 8、渲染结果
foreach ($rows as $r) {
echo '<h3'.htmlspecialchars($r['title']).'</h3';
echo '<p'.mb_substr(strip_tags($r['content']), 0, 150).'...</p';
echo '<hr';
}
// 9、分页条
if ($totalPages 1) {
echo '<div class=pager';
for ($i = 1; $i <= $totalPages; $i++) {
if ($i == $page) {
echo <strong$i</strong ;
} else {
echo '<a href=?q='.urlencode($keyword).'&page='.$i.''.$i.'</a ';
}
}
echo '</div';
}
?
四、几点常见坑
1、Sphinx 返回的 `total` 和 `total_found`
`total` 是 Sphinx 本次查询命中的文档数(受 `max_matches` 限制)。
`total_found` 才是真实总条数,拿它做分页。
如果 `total_found` 太大,可在 sphinx.conf 里把 `max_matches` 调大,例如 `max_matches = 10000`。
2、排序一致性
Sphinx 里用 `SetSortMode` 排好序后,MySQL 里用 `ORDER BY FIELD(id,...)` 保持同样顺序,否则分页会乱。
3、高亮
SphinxClient 自带 `BuildExcerpts`,可把关键词高亮:
php
$docs = array_column($rows, 'content');
$opts = ['before_match'='<b', 'after_match'='</b'];
$ex = $cl-BuildExcerpts($docs, 'myidx', $keyword, $opts);
4、分布式索引/实时索引
生产环境往往把主索引 + 增量索引 做成分布式,代码里把索引名改成 `myidx_main, myidx_delta` 即可。
五、一句话总结
分页就是“Sphinx 只取 id → MySQL 补数据 → 用 total_found 算页码”,代码 50 行左右就能跑通。
📣 商家广告 :
👍
0
👎
IP地址: 123.142.87.10
搜索次数: 0
提问时间: 2025-11-11 05:05:05
🛒 域名购买 :
jqr.sale 81.biz qn.gs 9el.cn che.red 84.gs oz.gs 5.hi.cn m.tj.cn xuanhuo.com.cn
❓️ 热门提问 :
国内vps带宽 mcjava服务器 百度云服务器 1.8米机柜 短视频源码服务器要求 机柜租赁报价 拨号云 支持更换ip的vps vps搭建代理ip 云vps日本 豌豆Ai站群搜索引擎系统
🌐 域名评估 :
5a.gd.cn zspy.cn che.red 39.cx eezl.cn tt.jl.cn pjku.cn aw.cq.cn sf.xj.cn earth2200.com.cn
⛏ 最新挖掘 :
凯里酸汤鱼 贵阳烤脑花 都匀毛尖茶 花溪牛肉粉 贵阳烤生蚝 贵阳烤豆腐 贵阳纸包鱼 贵阳特色菜
🖌 热门作画 :
🤝 关于我们:
豌豆Ai
域名
建站
站群
留痕
推广
评估
源码
开发Ai
工具
日记
价格
加盟
广告
流量
留言
联系
🗨 加入群聊 :
🔗 友情链接 :
贵阳用友政务
Ai站群
ai提问
🧰 站长工具 :Ai工具 whois查询 搜索
📢 温馨提示 :本站所有问答由Ai自动创作,内容仅供参考,若有误差请用“联系”里面信息通知我们人工修改或删除。
👉 技术支持 :本站由豌豆Ai 提供技术支持,使用的最新版:《豌豆Ai站群搜索引擎系统 V.25.10.25》搭建本站。