一、发现问题:搜索结果只有274条
升级到帝国CMS 8.0后,我发现后台高级搜索出现了一个奇怪的问题:
现象:
-
数据库明明有几万条数据,搜索结果却始终只有274条
-
同一个搜索条件,在7.5版本下完全正常
-
后台“搜索结果数量限制”无论设400还是1000,甚至设为“不限”,结果依然是274条
这显然不是配置问题,而是代码层面的bug。
二、排查过程:追踪代码,找到真凶
第一步:定位关键代码
打开 /e/search/result/index.php,找到核心处理逻辑:
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 3000, 1);
$search_num = (int)$getids_r['num'];
这里调用了一个叫 eSqlToGetids 的函数,参数中的 3000 引起了我的注意。
第二步:深入函数内部
打开 /e/class/connect.php,找到 eSqlToGetids 函数:
function eSqlToGetids($query, $idtype = 0, $maxnum = 0, $maxlen = 0, $mustlen = 1) {
while ($r = $empire->fetch($sql)) {
$num++;
// 限制1:数量限制
if ($maxnum && $num > $maxnum) break;
// 限制2:长度限制(关键!)
if ($maxlen && strlen($ids) >= $maxlen) break;
// 填充空格
if ($mustlen == 1) {
$thisid = eStrAddBlank($thisid, 10);
}
}
}
真相浮出水面:这个函数有两个限制条件——数量限制(maxnum)** 和 **长度限制(maxnum)∗∗和∗∗长度限制(maxlen)。
第三步:发现两个关键问题
问题一:长度限制覆盖了数量限制
后台的 searchupnum 传给了 $maxnum,但真正起限制作用的是 $maxlen。当 $maxlen=3000 时,$ids 字符串最长只能存3000个字符,这才导致结果被截断在274条左右。
问题二:空格填充浪费空间
当 $mustlen=1 时,每个ID会被填充空格到固定10位。原本 12345 只占5位,加上逗号是6位;填充后就变成了10位,空间利用率直接打了六折。
第四步:验证结论
查看数据库 enewssearch 表的 andsql 字段,发现了决定性的证据:
| 搜索记录 | result_num | andsql格式 | 说明 |
|---|---|---|---|
| 记录1 | 8335 | 纯逗号分隔(无空格) | ✅ 正常 |
| 记录2 | 2990 | 逗号+多个空格 | ❌ 被截断 |
问题根源确认:
-
限制搜索结果的不是后台的
searchupnum设置 -
而是
$maxlen+$mustlen=1的组合,导致andsql字段长度不够
三、解决方案
方案一:去掉空格填充(推荐)
修改 /e/search/result/index.php:
// 原代码
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 3000, 1);
// 修改后:把第5个参数改成0,去掉空格填充
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 50000, 0);
这样每个ID不再填充空格,50000字符可存储约8000+条5位数ID。
方案二:扩大长度限制
如果必须保留空格填充,就需要调大 $maxlen 并升级数据库字段:
// 把50000调大到200000
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 200000, 1);
同时执行SQL升级字段类型:
ALTER TABLE `{$dbtbpre}enewssearch` MODIFY COLUMN `andsql` MEDIUMTEXT;
方案三:彻底根治
修改 eSqlToGetids 函数,删除长度限制:
// 注释或删除这行
// if ($maxlen && strlen($ids) >= $maxlen) break;
这样搜索结果完全由后台的 searchupnum 控制,逻辑最清晰。
四、总结
问题本质:
帝国CMS 8.0的搜索机制中,$maxlen(字符长度限制)的优先级高于后台的 searchupnum(数量限制),加上 $mustlen=1 导致的空格填充,使得实际能存储的ID数量远低于预期。
我的最终选择:
采用方案一(去掉空格填充),并将 $maxlen 设置为500000,同时确认 andsql 字段为 mediumtext 类型。
修改后效果:
| 项目 | 修改前 | 修改后 |
|---|---|---|
| 实际数据量 | 25720条 | 25720条 |
| 搜索结果 | 274条 | 25720条 ✅ |
| 后台设置 | 不生效 | 完全生效 ✅ |
未经允许不得转载:YESKYLOG » 帝国CMS 8.0高级搜索条数限制问题:从发现到解决

微信关注,获取更多


最新评论