PHPIN.NET

 找回密码
 立即注册
查看: 7163|回复: 0

[技巧手记] 帝国CMS搜索优化(支持多关键字词空格搜索结果)

[复制链接]

469

主题

31

回帖

5497

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5497
发表于 2015-3-12 16:29:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
帝国CMS搜索优化(支持多关键字词空格搜索结果)

本方法带来的其他影响因素暂未测试(目前已知热门搜索关键字词调用的时候,关键字也是带有空格的。暂未发现其他)
简单优化了下官方的默认搜索系统,让搜索支持多个关键字词之间可以使用空格区分(两个关键词之间多少空格都无所谓,多个关键词也无所谓,都支持)
效果截图,搜索前:
搜索前.png

效果截图,搜索后:
搜索后.png 后台搜索记录截图:
后台搜索记录.png

修改方法,打开/e/search/index.php
1、找到:
  1. //处理关键字
  2. function SearchDoKeyboardVar($keyboard){
  3.         $keyboard=RepPostVar2(trim($keyboard));
  4.         $keyboard=str_replace('  ','',$keyboard);
  5.         return $keyboard;
  6. }
复制代码
修改为:
  1. //处理关键字
  2. function SearchDoKeyboardVar($keyboard){
  3.     $keyboard = RepPostVar2(trim($keyboard));
  4.     $keyboard = preg_replace('/[\s]+/s', ' ', $keyboard);
  5.     return $keyboard;
  6. }
复制代码

2、找到:
  1. //(有两处,修改第二处)
  2. $where=$f." LIKE '%".$keyboard."%'";
  3. 7.0版为:
  4. $where=$f." LIKE '%".str_replace(" ","%",$keyboard)."%'";
复制代码
修改为:
  1.        // 关键字处理
  2.         $arr = explode(' ', $keyboard);
  3.         foreach ($arr as $val){
  4.             $tj.=$f." like '%".$val."%' or ";
  5.         }
  6.         $where = substr($tj, 0, -4);
复制代码


这样即可。
懒人直接复制以下代码替换/e/search/index.php中所有代码即可
/e/search/index.php:
  1. <?php
  2. require("../class/connect.php");
  3. require("../class/db_sql.php");
  4. require("../data/dbcache/class.php");
  5. require("../class/q_functions.php");
  6. eCheckCloseMods('search');//关闭模块
  7. $link=db_connect();
  8. $empire=new mysqlquery();

  9. //处理关键字
  10. function SearchDoKeyboardVar($keyboard){
  11.     $keyboard = RepPostVar2(trim($keyboard));
  12.     $keyboard = preg_replace('/[\s]+/s', ' ', $keyboard);
  13.     return $keyboard;
  14. }

  15. //返回SQL
  16. function SearchDoKeyboard($f,$hh,$keyboard){
  17.         $where='';
  18.         $keyboard=SearchDoKeyboardVar($keyboard);
  19.         if(empty($keyboard))
  20.         {
  21.                 return "";
  22.         }
  23.         if(!empty($hh))
  24.         {
  25.                 if($hh=='LT')//小于
  26.                 {
  27.                         $where=$f."<'".$keyboard."'";
  28.                 }
  29.                 elseif($hh=='GT')//大于
  30.                 {
  31.                         $where=$f.">'".$keyboard."'";
  32.                 }
  33.                 elseif($hh=='EQ')//等于
  34.                 {
  35.                         $where=$f."='".$keyboard."'";
  36.                 }
  37.                 elseif($hh=='LE')//小于等于
  38.                 {
  39.                         $where=$f."<='".$keyboard."'";
  40.                 }
  41.                 elseif($hh=='GE')//大于等于
  42.                 {
  43.                         $where=$f.">='".$keyboard."'";
  44.                 }
  45.                 elseif($hh=='NE')//不等于
  46.                 {
  47.                         $where=$f."<>'".$keyboard."'";
  48.                 }
  49.                 elseif($hh=='IN')//包含
  50.                 {
  51.                         $kr=explode(' ',$keyboard);
  52.                         $kcount=count($kr);
  53.                         $kbs='';
  54.                         $dh='';
  55.                         for($i=0;$i<$kcount;$i++)
  56.                         {
  57.                                 $kr[$i]=(float)$kr[$i];
  58.                                 if(empty($kr[$i]))
  59.                                 {
  60.                                         continue;
  61.                                 }
  62.                                 if($kbs)
  63.                                 {
  64.                                         $dh=',';
  65.                                 }
  66.                                 $kbs.=$dh."'".$kr[$i]."'";
  67.                         }
  68.                         if($kbs)
  69.                         {
  70.                                 $where=$f." IN (".$kbs.")";
  71.                         }
  72.                         else
  73.                         {
  74.                                 return '';
  75.                         }
  76.                 }
  77.                 elseif($hh=='BT')//范围
  78.                 {
  79.                         $keyboard=ltrim($keyboard);
  80.                         if(!strstr($keyboard,' '))
  81.                         {
  82.                                 return '';
  83.                         }
  84.                         $kr=explode(' ',$keyboard);
  85.                         $kr[0]=(float)$kr[0];
  86.                         $kr[1]=(float)$kr[1];
  87.                         if(!trim($kr[0])||!trim($kr[1]))
  88.                         {
  89.                                 return '';
  90.                         }
  91.                         $where=$f." BETWEEN '".$kr[0]."' and '".$kr[1]."'";
  92.                 }
  93.                 else//相似
  94.                 {
  95.                         $where=$f." LIKE '%".$keyboard."%'";
  96.                 }
  97.         }
  98.         else
  99.         {
  100.                 //$where=$f." LIKE '%".str_replace(" ","%",$keyboard)."%'";
  101.                 // 关键字处理
  102.                 $arr = explode(' ', $keyboard);
  103.                 foreach ($arr as $val){
  104.                     $tj.=$f." like '%".$val."%' or ";
  105.                 }
  106.                 $where = substr($tj, 0, -4);
  107.         }
  108.         return $where;
  109. }

  110. //变量
  111. if($_GET['searchget']==1)
  112. {
  113.         $_POST=$_GET;
  114. }

  115. $ip=egetip();
  116. $searchtime=time();
  117. $getvar=$_POST['getvar'];
  118. if(empty($getvar))
  119. {
  120.         $getfrom="history.go(-1)";
  121.         $dogetvar='';
  122. }
  123. else
  124. {
  125.         $getfrom="../../search/";
  126.         $dogetvar="&getvar=1";
  127. }
  128. //返回
  129. $getfrom=DoingReturnUrl($getfrom,$_POST['ecmsfrom']);
  130. //搜索用户组
  131. if($public_r['searchgroupid'])
  132. {
  133.         $psearchgroupid=$public_r['searchgroupid'];
  134.         @include("../data/dbcache/MemberLevel.php");
  135.         $searchgroupid=(int)getcvar('mlgroupid');
  136.         if($level_r[$searchgroupid][level]<$level_r[$psearchgroupid][level])
  137.         {
  138.                 printerror("NotLevelToSearch",$getfrom,1);
  139.         }
  140. }
  141. //搜索间隔
  142. $lastsearchtime=getcvar('lastsearchtime');
  143. if($lastsearchtime)
  144. {
  145.         if($searchtime-$lastsearchtime<$public_r[searchtime])
  146.         {
  147.                 printerror("SearchOutTime",$getfrom,1);
  148.         }
  149. }
  150. //搜索字段
  151. $searchclass=$_POST['show'];
  152. if(empty($searchclass)||@strstr($searchclass," "))
  153. {
  154.         printerror("SearchNotRecord",$getfrom,1);
  155. }
  156. //时间范围
  157. $add='';
  158. $addtime='';
  159. $starttime=RepPostVar($_POST['starttime']);
  160. if(empty($starttime))
  161. {
  162.         $starttime="0000-00-00";
  163. }
  164. $endtime=RepPostVar($_POST['endtime']);
  165. if(empty($endtime))
  166. {
  167.         $endtime="0000-00-00";
  168. }
  169. if($endtime!="0000-00-00")
  170. {
  171.         $addtime=" and (newstime BETWEEN '".to_time($starttime." 00:00:00")."' and '".to_time($endtime." 23:59:59")."')";
  172. }
  173. //价格
  174. $addprice='';
  175. $startprice=(int)$_POST['startprice'];
  176. $endprice=(int)$_POST['endprice'];
  177. if($endprice)
  178. {
  179.         $addprice=" and (price BETWEEN ".$startprice." and ".$endprice.")";
  180. }
  181. //搜索栏目及表
  182. $classid=RepPostVar($_POST['classid']);
  183. $s_tbname=RepPostVar($_POST['tbname']);
  184. $s_tempid=(int)$_POST['tempid'];
  185. $trueclassid=0;
  186. if($classid)//按栏目
  187. {
  188.         if(strstr($classid,","))//多栏目
  189.         {
  190.                 $son_r=sys_ReturnMoreClass($classid,1);
  191.                 $trueclassid=$son_r[0];
  192.                 $add.=' and ('.$son_r[1].')';
  193.         }
  194.         else
  195.         {
  196.                 $trueclassid=intval($classid);
  197.                 $add.=$class_r[$trueclassid][islast]?" and classid='$trueclassid'":" and ".ReturnClass($class_r[$trueclassid][sonclass]);
  198.         }
  199.         $tbname=$class_r[$trueclassid][tbname];
  200.         $modid=$class_r[$trueclassid][modid];
  201. }
  202. elseif($s_tbname)//按数据表
  203. {
  204.         $tbnamenum=$empire->gettotal("select count(*) as total from {$dbtbpre}enewstable where tbname='$s_tbname' limit 1");
  205.         if(!$tbnamenum)
  206.         {
  207.                 printerror("SearchNotRecord",$getfrom,1);
  208.         }
  209.         $tbname=$s_tbname;
  210.         //模型id
  211.         $thestemp_r=$empire->fetch1("select modid from ".GetTemptb("enewssearchtemp")." where tempid='$s_tempid'");
  212.         if(empty($thestemp_r['modid']))
  213.         {
  214.                 printerror("SearchNotRecord",$getfrom,1);
  215.         }
  216.         $modid=$thestemp_r['modid'];
  217. }
  218. else
  219. {
  220.         $tbname=$public_r['tbname'];
  221.         $modid=0;
  222. }
  223. //表不存在
  224. if(empty($tbname)||InfoIsInTable($tbname))
  225. {
  226.         printerror("SearchNotRecord",$getfrom,1);
  227. }
  228. //标题分类
  229. $ttid=RepPostVar($_POST['ttid']);
  230. $truettid=0;
  231. if($ttid)
  232. {
  233.         if(strstr($ttid,","))//多标题分类
  234.         {
  235.                 $son_r=sys_ReturnMoreTT($ttid);
  236.                 $truettid=$son_r[0];
  237.                 $add.=' and ('.$son_r[1].')';
  238.         }
  239.         else
  240.         {
  241.                 $truettid=intval($ttid);
  242.                 $add.=" and ttid='$truettid'";
  243.         }
  244. }
  245. //会员
  246. $member=$_POST['member'];
  247. if($member==1)
  248. {
  249.         $add.=' and ismember=1';
  250. }
  251. elseif($member==2)
  252. {
  253.         $add.=' and ismember=0';
  254. }
  255. //模型
  256. $tempr=array();
  257. if(empty($class_r[$trueclassid][searchtempid]))
  258. {
  259.         if(empty($modid))
  260.         {
  261.                 $tempr=$empire->fetch1("select modid from ".GetTemptb("enewssearchtemp")." where isdefault=1 limit 1");
  262.         }
  263.         else
  264.         {
  265.                 $tempr[modid]=$modid;
  266.         }
  267. }
  268. else
  269. {
  270.         $tempr[modid]=$modid;
  271. }

  272. //关键字
  273. $keyboard=$_POST['keyboard'];
  274. $keyboardone=0;
  275. if(is_array($keyboard))
  276. {}
  277. elseif(strstr($keyboard,','))
  278. {
  279.         $keyboard=explode(',',$keyboard);
  280. }
  281. else
  282. {
  283.         $keyboard=trim($keyboard);
  284.         $len=strlen($keyboard);
  285.         if($len<$public_r[min_keyboard]||$len>$public_r[max_keyboard])
  286.         {
  287.                 printerror("MinKeyboard",$getfrom,1);
  288.         }
  289.         $keyboardone=1;
  290. }

  291. //符号
  292. $hh=$_POST['hh'];
  293. $hhone=0;
  294. if(is_array($hh))
  295. {}
  296. elseif(strstr($hh,','))
  297. {
  298.         $hh=explode(',',$hh);
  299. }
  300. else
  301. {
  302.         $hhone=1;
  303. }

  304. //字段
  305. if(!is_array($searchclass))
  306. {
  307.         $searchclass=explode(',',$searchclass);
  308. }

  309. $andor=$_POST['andor'];
  310. $andor=$andor=='and'?'and':'or';

  311. $mr=$empire->fetch1("select searchvar,tbname from {$dbtbpre}enewsmod where mid='$tempr[modid]'");
  312. if(!strstr($mr[searchvar],",price,"))//是否包含价格
  313. {
  314.         $addprice="";
  315.         $startprice=0;
  316.         $endprice=0;
  317. }
  318. //搜索特殊字段
  319. $mr[searchvar].='id,keyboard,userid,username,';
  320. $where='';
  321. $newsearchclass='';
  322. $count=count($searchclass);
  323. for($i=0;$i<$count;$i++)
  324. {
  325.         if(empty($searchclass[$i]))
  326.         {
  327.                 continue;
  328.         }
  329.         $searchclass[$i]=str_replace(',','',$searchclass[$i]);
  330.         if(!strstr($mr[searchvar],",".$searchclass[$i].","))
  331.         {
  332.                 continue;
  333.         }
  334.         $searchclass[$i]=RepPostVar($searchclass[$i]);
  335.         $dh=empty($newsearchclass)?'':',';
  336.         $newsearchclass.=$dh.$searchclass[$i];
  337.         $dohh=$hhone==1?$hh:$hh[$i];
  338.         $dokeyboard=$keyboardone==1?$keyboard:$keyboard[$i];
  339.         $onewhere=SearchDoKeyboard($searchclass[$i],$dohh,$dokeyboard);
  340.         if($onewhere)
  341.         {
  342.                 $or=empty($where)?'':' '.$andor.' ';
  343.                 $where.=$or.'('.$onewhere.')';
  344.         }
  345. }
  346. //参数错
  347. if(empty($newsearchclass))
  348. {
  349.         printerror("SearchNotRecord",$getfrom,1);
  350. }
  351. if($where)
  352. {
  353.         $add.=' and ('.$where.')';
  354. }
  355. $allwhere=$add.$addtime.$addprice;
  356. $keyboard=$keyboardone==1?SearchDoKeyboardVar($keyboard):'';
  357. $andsql=addslashes($allwhere);
  358. if(strlen($newsearchclass)>250||strlen($classid)>200||strlen($andsql)>3000||strlen($keyboard)>100||strlen($ttid)>200)
  359. {
  360.         printerror("SearchNotRecord",$getfrom,1);
  361. }
  362. //验证码
  363. $checkpass=md5($allwhere.$tbname);
  364. $query="select count(*) as total from {$dbtbpre}ecms_".$tbname.($allwhere?' where '.substr($allwhere,5):'');
  365. $search_r=$empire->fetch1("select searchid from {$dbtbpre}enewssearch where checkpass='$checkpass' limit 1");
  366. $searchid=$search_r[searchid];
  367. //排序
  368. $orderby=RepPostVar($_POST['orderby']);
  369. $myorder=(int)$_POST['myorder'];
  370. if($orderby)
  371. {
  372.         $orderr=ReturnDoOrderF($tempr[modid],$orderby,$myorder);
  373.         $orderby=$orderr['returnf'];
  374. }
  375. else
  376. {
  377.         $orderby='newstime';
  378. }
  379. //是否有历史记录
  380. if($searchid)
  381. {
  382.     $search_num=$empire->gettotal($query);
  383.         $sql=$empire->query("update {$dbtbpre}enewssearch set searchtime='$searchtime',result_num='$search_num',onclick=onclick+1,orderby='$orderby',myorder='$myorder',tempid='$s_tempid' where searchid='$searchid'");
  384.         if(empty($search_num))
  385.         {
  386.                 $searchid=0;
  387.         }
  388. }
  389. else
  390. {
  391.         $search_num=$empire->gettotal($query);
  392.         if(empty($search_num))
  393.         {
  394.                 $searchid=0;
  395.         }
  396.         else
  397.         {
  398.                 $iskey=$keyboardone==1?0:1;
  399.                 $sql=$empire->query("insert into {$dbtbpre}enewssearch(searchtime,keyboard,searchclass,result_num,searchip,classid,onclick,orderby,myorder,checkpass,tbname,tempid,iskey,andsql,trueclassid) values('$searchtime','$keyboard','$newsearchclass','$search_num','$ip','$classid',1,'$orderby','$myorder','$checkpass','$tbname','$s_tempid','$iskey','$andsql','$trueclassid')");
  400.                 $searchid=$empire->lastid();
  401.         }
  402. }
  403. //设置最后搜索时间
  404. $set1=esetcookie("lastsearchtime",$searchtime,$searchtime+3600*24);
  405. if(!$searchid)
  406. {
  407.         printerror("SearchNotRecord",$getfrom,1);
  408. }
  409. else
  410. {
  411.         Header("Location:result/?searchid=$searchid".$dogetvar);
  412. }
  413. db_close();
  414. $empire=null;
  415. ?>
复制代码


如果你的搜索做过 帝国CMS搜索结果关键字高亮
请使用一下方法替代
修改e/search/result/index.php
找到
  1. $changerow+=1;
复制代码

在这句代码的前面加上代码:
  1.   $listtext = keyboardHighlight($search_r['keyboard'], $listtext); // 搜索关键词高亮
复制代码

在页面中加入下面函数
  1. // 关键字都加高亮
  2. function keyboardHighlight($keyboard, $listtext){
  3.         $arr = explode(' ', $keyboard);
  4.         $newArr = array_map(function ($item){
  5.             return '<em>' . $item . '</em>';
  6.         }, $arr);
  7.         return str_replace($arr, $newArr, $listtext);
  8. }
复制代码


本方法兼容帝国CMS7.0/7.2,其他版本暂未测试。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|PHPIN.NET ( 冀ICP备12000898号-14 )|网站地图

GMT+8, 2024-3-28 21:16

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表