phpcms v9程序由gbk编码转为utf8编码后使用站内搜索返回结果为空的问题
编者按: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%'";
保存后更新全站缓存测试即可。
