技术日志

记录分享邓杰律师从事网络技术工作点点滴滴。

phpcms v9程序由gbk编码转为utf8编码后使用站内搜索返回结果为空的问题

点击复制标题网址

——温馨提示——

已复制到剪贴板,可粘贴到下一处。


时间:2026-01-19   查看:1019

编者按:phpcms v9用utf8官方程序版本全新安装,原数据库gbk编码全部转为utf8且确认所有字符都是utf8,之前使用gbk编码时,用网站前台搜索程序检索关键词结果正常。转为utf8后仅后台搜索正常,前台搜索结果为零。本文给出了针对性解决方案。

phpcms v9用utf8官方程序版本全新安装,原数据库gbk编码全部转为utf8且确认所有字符都是utf8,之前使用gbk编码时,用网站前台搜索程序检索关键词结果正常。转为utf8后仅后台搜索正常,前台搜索结果为零。原因就是

使用了 segment 类进行分词(GBK 编码专用),在 UTF-8 环境下分词失败 → $segment_q 为空 → 搜索逻辑降级为 LIKE '%$q%',但因 MySQL 全文索引或字段编码问题仍可能匹配不到结果。

pc_base::load_sys_class('segment', '', 0);

加载的是 /phpcms/libs/classes/segment.class.php —— 该类内部硬编码按 GBK 处理中文字符(如 ord($str[$i]) > 0x80 判断双字节),在 UTF-8 下会错误切分,导致 get_keyword() 返回空。

即使 $segment_q 为空,理论上应走 LIKE '%$q%' 路径,但若数据库字段是 utf8mb4 而连接未设 SET NAMES utf8mb4,或关键词含特殊字符,仍可能匹配失败。

解决方案:

彻底绕过 segment 分词器,强制使用原始关键词全文模糊搜索

这是最安全、高效、兼容 UTF-8 的做法,尤其适合已转 UTF-8 的站点。

针对该问题,对/phpcms/modules/search/index.php相应地方进行修改即可。具体如下:

查找到:

pc_base::load_sys_class('segment', '', 0); $segment = new segment(); //分词结果 $segment_q = $segment->get_keyword($segment->split_result($q)); //如果分词结果为空 if(!empty($segment_q)) {    $sql = "`siteid`= '$siteid' AND `typeid` = '$typeid' $sql_time AND MATCH (`data`) AGAINST ('$segment_q' IN BOOLEAN MODE)"; } else {    $sql = "`siteid`= '$siteid' AND `typeid` = '$typeid' $sql_time AND `data` like '%$q%'"; }

替换为:

// 【UTF-8 修复】跳过 GBK 分词器,直接使用原始关键词进行模糊搜索 $segment_q = ''; // 强制留空,避免干扰 $sql = "`siteid`= '$siteid' AND `typeid` = '$typeid' $sql_time AND `data` LIKE '%$q%'";


保存后更新全站缓存测试即可。


发表评论:

评论记录:

未查询到任何数据!