一、问题发现
在将帝国CMS从7.5版本升级到8.0后,发现高级搜索出现两个严重问题:
-
搜索结果数量被限制:数据库明明有几万条数据,搜索结果却始终只有274条,后台设置的“搜索结果数量限制”完全不生效。
-
大页码无法显示:搜索结果有857页,但只能点到198页,之后的页码均提示“没有搜索到相关的内容”。
二、问题排查过程
2.1 搜索结果数量限制问题
通过追踪代码发现,/e/search/index.php 中调用了 eSqlToGetids 函数:
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 3000, 1);
该函数有两个限制条件:
-
$maxnum:后台设置的搜索数量限制(如1000条) -
$maxlen:字符串长度限制(默认3000字符)
问题根源:$maxlen=3000 的字符长度限制优先级高于后台设置,且 $mustlen=1 导致每个ID被填充空格到固定10位,空间利用率只有60%,实际能存储的ID数量远低于预期。
2.2 大页码无法显示问题
通过追踪代码发现,/e/search/result/index.php 中调用了 eGetidsLimitMlen 函数:
$pageids = eGetidsLimitMlen($search_r['andsql'], 10, $line, $page, 1);
该函数通过字符串截取方式实现分页,当页码较大时计算偏移量出错,导致返回空值。
问题根源:字符串截取方式在处理大数据量和大页码时不稳定,且 andsql 字段类型为 text(最大65535字符),无法存储完整的ID列表。
三、解决方案
3.1 修改 /e/search/index.php
找到代码(约第236行):
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 3000, 1);
修改为:
//--yeskylog_modify $maxlen限制增大到500000 存储约80000+条5位数ID 取消$mustlen占位符 2026/6/11
$getids_r = eSqlToGetids($queryids, 0, $public_r['searchupnum'], 500000, 0);
修改说明:
| 参数 | 原值 | 新值 | 作用 |
|---|---|---|---|
| 第4个参数 | 3000 | 500000 | 增大字符串长度限制 |
| 第5个参数 | 1 | 0 | 取消ID空格填充 |
3.2 修改 /e/search/result/index.php
找到代码(约第46-56行):
//ids
$pageids=eGetidsLimitMlen($search_r['andsql'],10,$line,$page,1);
if(!$pageids)
{
printerror("SearchNotRecord",$getfrom,1);
}
$query="select * from {$dbtbpre}ecms_".$search_r['tbname']." where id in (".$pageids.")";
//$query.=" order by ".$myorder."".do_dblimit($line,$offset);
$query.=" order by ".$myorder."";
修改为:
//--yeskylog_modify ids - 取消eGetidsLimitMlen函数返回ID列表(固定字符) 直接数组分割分页 2026/6/11
$ids_clean = str_replace(' ', '', $search_r['andsql']);
$id_arr = explode(',', $ids_clean);
$total_ids = count($id_arr);
$start = $page * $line;
if ($start >= $total_ids) {
printerror("SearchNotRecord", $getfrom, 1);
}
$page_ids = array_slice($id_arr, $start, $line);
if (empty($page_ids)) {
printerror("SearchNotRecord", $getfrom, 1);
}
$pageids = implode(',', $page_ids);
$query = "select * from {$dbtbpre}ecms_" . $search_r['tbname'] . " where id in (" . $pageids . ")";
$query .= " order by " . $myorder;
//--yeskylog_modify ids - 取消eGetidsLimitMlen函数返回ID列表(固定字符) 直接数组分割分页 2026/6/11
3.3 升级数据库字段类型
执行SQL,将 andsql 字段从 text 升级为 mediumtext:
ALTER TABLE `{$dbtbpre}enewssearch` MODIFY COLUMN `andsql` MEDIUMTEXT;
字段容量对比:
| 字段类型 | 最大字符数 | 可存5位数ID数量 |
|---|---|---|
text |
65,535 | 约10,900条 |
mediumtext |
16,777,215 | 约2,796,000条 |
四、修改前后对比
| 问题 | 修改前 | 修改后 |
|---|---|---|
| 搜索结果数量 | 最多274条 | 按后台设置正常显示 |
| 分页支持 | 最多198页 | 支持全部857页 |
| 国产数据库兼容 | 依赖复杂函数 | ✅ 完全兼容 |
andsql 字段类型 |
text(65535字符) |
mediumtext(16MB) |
五、国产数据库兼容性说明
新方案的核心是使用 explode + array_slice 进行数组分割分页,生成的SQL为标准语法:
SELECT * FROM table WHERE id IN (id1,id2,id3,...) ORDER BY newstime DESC
该SQL所有数据库均支持:
-
✅ MySQL / MariaDB
-
✅ PostgreSQL
-
✅ 华为高斯 openGauss
-
✅ 金仓数据库 KingbaseES
-
✅ 瀚高数据库
六、总结
本次修改解决了帝国CMS 8.0高级搜索的两个核心问题:
-
搜索结果数量限制问题:通过调大
$maxlen参数并取消ID空格填充,让后台设置真正生效。 -
大页码分页问题:用数组分割替代字符串截取,彻底解决了大页码报错问题。
修改后的代码不仅稳定可靠,而且完全兼容国产数据库,可满足信创项目部署要求。
下面是修复的好附件
上传以下附件:
通过网盘分享的文件:e.zip
链接: https://pan.baidu.com/s/1g6rzLBd0C9Ck0d8b_KF_tg?pwd=9cim 提取码: 9cim 复制这段内容后打开百度网盘手机App,操作更方便哦
未经允许不得转载:YESKYLOG » 帝国CMS 8.0 高级搜索分页与数量限制问题完整解决方案

微信关注,获取更多


最新评论