一、发现问题:搜索结果只有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']; PHP 这里调用了一个叫 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); } } } PHP 真相浮出水面:这个函数有两个限制条件——数量限制(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); PHP 这样每个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; PHP 方案三:彻底根治 修改 eSqlToGetids 函数,删除长度限制:
// 注释或删除这行 // if ($maxlen && strlen($ids) >= $maxlen) break; PHP 这样搜索结果完全由后台的 searchupnum 控制,逻辑最清晰。
四、总结 问题本质:
帝国CMS 8.0的搜索机制中,$maxlen(字符长度限制)的优先级高于后台的 searchupnum(数量限制),加上 $mustlen=1 导致的空格填充,使得实际能存储的ID数量远低于预期。
我的最终选择:
采用方案一(去掉空格填充),并将 $maxlen 设置为500000,同时确认 andsql 字段为 mediumtext 类型。
修改后效果:
项目 修改前 修改后 实际数据量 25720条 25720条 搜索结果 274条 25720条 ✅ 后台设置 不生效 完全生效 ✅ 原文地址https://www.yeskylog.com/ecms/200.html
|