admin 发表于 2015-3-12 16:29:44

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

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

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


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


修改方法,打开/e/search/index.php
1、找到://处理关键字
function SearchDoKeyboardVar($keyboard){
      $keyboard=RepPostVar2(trim($keyboard));
      $keyboard=str_replace('','',$keyboard);
      return $keyboard;
}修改为://处理关键字
function SearchDoKeyboardVar($keyboard){
    $keyboard = RepPostVar2(trim($keyboard));
    $keyboard = preg_replace('/[\s]+/s', ' ', $keyboard);
    return $keyboard;
}
2、找到://(有两处,修改第二处)
$where=$f." LIKE '%".$keyboard."%'";
7.0版为:
$where=$f." LIKE '%".str_replace(" ","%",$keyboard)."%'";
修改为:       // 关键字处理
      $arr = explode(' ', $keyboard);
      foreach ($arr as $val){
            $tj.=$f." like '%".$val."%' or ";
      }
      $where = substr($tj, 0, -4);

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

//处理关键字
function SearchDoKeyboardVar($keyboard){
    $keyboard = RepPostVar2(trim($keyboard));
    $keyboard = preg_replace('/[\s]+/s', ' ', $keyboard);
    return $keyboard;
}

//返回SQL
function SearchDoKeyboard($f,$hh,$keyboard){
      $where='';
      $keyboard=SearchDoKeyboardVar($keyboard);
      if(empty($keyboard))
      {
                return "";
      }
      if(!empty($hh))
      {
                if($hh=='LT')//小于
                {
                        $where=$f."<'".$keyboard."'";
                }
                elseif($hh=='GT')//大于
                {
                        $where=$f.">'".$keyboard."'";
                }
                elseif($hh=='EQ')//等于
                {
                        $where=$f."='".$keyboard."'";
                }
                elseif($hh=='LE')//小于等于
                {
                        $where=$f."<='".$keyboard."'";
                }
                elseif($hh=='GE')//大于等于
                {
                        $where=$f.">='".$keyboard."'";
                }
                elseif($hh=='NE')//不等于
                {
                        $where=$f."<>'".$keyboard."'";
                }
                elseif($hh=='IN')//包含
                {
                        $kr=explode(' ',$keyboard);
                        $kcount=count($kr);
                        $kbs='';
                        $dh='';
                        for($i=0;$i<$kcount;$i++)
                        {
                              $kr[$i]=(float)$kr[$i];
                              if(empty($kr[$i]))
                              {
                                        continue;
                              }
                              if($kbs)
                              {
                                        $dh=',';
                              }
                              $kbs.=$dh."'".$kr[$i]."'";
                        }
                        if($kbs)
                        {
                              $where=$f." IN (".$kbs.")";
                        }
                        else
                        {
                              return '';
                        }
                }
                elseif($hh=='BT')//范围
                {
                        $keyboard=ltrim($keyboard);
                        if(!strstr($keyboard,' '))
                        {
                              return '';
                        }
                        $kr=explode(' ',$keyboard);
                        $kr=(float)$kr;
                        $kr=(float)$kr;
                        if(!trim($kr)||!trim($kr))
                        {
                              return '';
                        }
                        $where=$f." BETWEEN '".$kr."' and '".$kr."'";
                }
                else//相似
                {
                        $where=$f." LIKE '%".$keyboard."%'";
                }
      }
      else
      {
                //$where=$f." LIKE '%".str_replace(" ","%",$keyboard)."%'";
                // 关键字处理
                $arr = explode(' ', $keyboard);
                foreach ($arr as $val){
                  $tj.=$f." like '%".$val."%' or ";
                }
                $where = substr($tj, 0, -4);
      }
      return $where;
}

//变量
if($_GET['searchget']==1)
{
      $_POST=$_GET;
}

$ip=egetip();
$searchtime=time();
$getvar=$_POST['getvar'];
if(empty($getvar))
{
      $getfrom="history.go(-1)";
      $dogetvar='';
}
else
{
      $getfrom="../../search/";
      $dogetvar="&getvar=1";
}
//返回
$getfrom=DoingReturnUrl($getfrom,$_POST['ecmsfrom']);
//搜索用户组
if($public_r['searchgroupid'])
{
      $psearchgroupid=$public_r['searchgroupid'];
      @include("../data/dbcache/MemberLevel.php");
      $searchgroupid=(int)getcvar('mlgroupid');
      if($level_r[$searchgroupid]<$level_r[$psearchgroupid])
      {
                printerror("NotLevelToSearch",$getfrom,1);
      }
}
//搜索间隔
$lastsearchtime=getcvar('lastsearchtime');
if($lastsearchtime)
{
      if($searchtime-$lastsearchtime<$public_r)
      {
                printerror("SearchOutTime",$getfrom,1);
      }
}
//搜索字段
$searchclass=$_POST['show'];
if(empty($searchclass)||@strstr($searchclass," "))
{
      printerror("SearchNotRecord",$getfrom,1);
}
//时间范围
$add='';
$addtime='';
$starttime=RepPostVar($_POST['starttime']);
if(empty($starttime))
{
      $starttime="0000-00-00";
}
$endtime=RepPostVar($_POST['endtime']);
if(empty($endtime))
{
      $endtime="0000-00-00";
}
if($endtime!="0000-00-00")
{
      $addtime=" and (newstime BETWEEN '".to_time($starttime." 00:00:00")."' and '".to_time($endtime." 23:59:59")."')";
}
//价格
$addprice='';
$startprice=(int)$_POST['startprice'];
$endprice=(int)$_POST['endprice'];
if($endprice)
{
      $addprice=" and (price BETWEEN ".$startprice." and ".$endprice.")";
}
//搜索栏目及表
$classid=RepPostVar($_POST['classid']);
$s_tbname=RepPostVar($_POST['tbname']);
$s_tempid=(int)$_POST['tempid'];
$trueclassid=0;
if($classid)//按栏目
{
      if(strstr($classid,","))//多栏目
      {
                $son_r=sys_ReturnMoreClass($classid,1);
                $trueclassid=$son_r;
                $add.=' and ('.$son_r.')';
      }
      else
      {
                $trueclassid=intval($classid);
                $add.=$class_r[$trueclassid]?" and classid='$trueclassid'":" and ".ReturnClass($class_r[$trueclassid]);
      }
      $tbname=$class_r[$trueclassid];
      $modid=$class_r[$trueclassid];
}
elseif($s_tbname)//按数据表
{
      $tbnamenum=$empire->gettotal("select count(*) as total from {$dbtbpre}enewstable where tbname='$s_tbname' limit 1");
      if(!$tbnamenum)
      {
                printerror("SearchNotRecord",$getfrom,1);
      }
      $tbname=$s_tbname;
      //模型id
      $thestemp_r=$empire->fetch1("select modid from ".GetTemptb("enewssearchtemp")." where tempid='$s_tempid'");
      if(empty($thestemp_r['modid']))
      {
                printerror("SearchNotRecord",$getfrom,1);
      }
      $modid=$thestemp_r['modid'];
}
else
{
      $tbname=$public_r['tbname'];
      $modid=0;
}
//表不存在
if(empty($tbname)||InfoIsInTable($tbname))
{
      printerror("SearchNotRecord",$getfrom,1);
}
//标题分类
$ttid=RepPostVar($_POST['ttid']);
$truettid=0;
if($ttid)
{
      if(strstr($ttid,","))//多标题分类
      {
                $son_r=sys_ReturnMoreTT($ttid);
                $truettid=$son_r;
                $add.=' and ('.$son_r.')';
      }
      else
      {
                $truettid=intval($ttid);
                $add.=" and ttid='$truettid'";
      }
}
//会员
$member=$_POST['member'];
if($member==1)
{
      $add.=' and ismember=1';
}
elseif($member==2)
{
      $add.=' and ismember=0';
}
//模型
$tempr=array();
if(empty($class_r[$trueclassid]))
{
      if(empty($modid))
      {
                $tempr=$empire->fetch1("select modid from ".GetTemptb("enewssearchtemp")." where isdefault=1 limit 1");
      }
      else
      {
                $tempr=$modid;
      }
}
else
{
      $tempr=$modid;
}

//关键字
$keyboard=$_POST['keyboard'];
$keyboardone=0;
if(is_array($keyboard))
{}
elseif(strstr($keyboard,','))
{
      $keyboard=explode(',',$keyboard);
}
else
{
      $keyboard=trim($keyboard);
      $len=strlen($keyboard);
      if($len<$public_r||$len>$public_r)
      {
                printerror("MinKeyboard",$getfrom,1);
      }
      $keyboardone=1;
}

//符号
$hh=$_POST['hh'];
$hhone=0;
if(is_array($hh))
{}
elseif(strstr($hh,','))
{
      $hh=explode(',',$hh);
}
else
{
      $hhone=1;
}

//字段
if(!is_array($searchclass))
{
      $searchclass=explode(',',$searchclass);
}

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

$mr=$empire->fetch1("select searchvar,tbname from {$dbtbpre}enewsmod where mid='$tempr'");
if(!strstr($mr,",price,"))//是否包含价格
{
      $addprice="";
      $startprice=0;
      $endprice=0;
}
//搜索特殊字段
$mr.='id,keyboard,userid,username,';
$where='';
$newsearchclass='';
$count=count($searchclass);
for($i=0;$i<$count;$i++)
{
      if(empty($searchclass[$i]))
      {
                continue;
      }
      $searchclass[$i]=str_replace(',','',$searchclass[$i]);
      if(!strstr($mr,",".$searchclass[$i].","))
      {
                continue;
      }
      $searchclass[$i]=RepPostVar($searchclass[$i]);
      $dh=empty($newsearchclass)?'':',';
      $newsearchclass.=$dh.$searchclass[$i];
      $dohh=$hhone==1?$hh:$hh[$i];
      $dokeyboard=$keyboardone==1?$keyboard:$keyboard[$i];
      $onewhere=SearchDoKeyboard($searchclass[$i],$dohh,$dokeyboard);
      if($onewhere)
      {
                $or=empty($where)?'':' '.$andor.' ';
                $where.=$or.'('.$onewhere.')';
      }
}
//参数错
if(empty($newsearchclass))
{
      printerror("SearchNotRecord",$getfrom,1);
}
if($where)
{
      $add.=' and ('.$where.')';
}
$allwhere=$add.$addtime.$addprice;
$keyboard=$keyboardone==1?SearchDoKeyboardVar($keyboard):'';
$andsql=addslashes($allwhere);
if(strlen($newsearchclass)>250||strlen($classid)>200||strlen($andsql)>3000||strlen($keyboard)>100||strlen($ttid)>200)
{
      printerror("SearchNotRecord",$getfrom,1);
}
//验证码
$checkpass=md5($allwhere.$tbname);
$query="select count(*) as total from {$dbtbpre}ecms_".$tbname.($allwhere?' where '.substr($allwhere,5):'');
$search_r=$empire->fetch1("select searchid from {$dbtbpre}enewssearch where checkpass='$checkpass' limit 1");
$searchid=$search_r;
//排序
$orderby=RepPostVar($_POST['orderby']);
$myorder=(int)$_POST['myorder'];
if($orderby)
{
      $orderr=ReturnDoOrderF($tempr,$orderby,$myorder);
      $orderby=$orderr['returnf'];
}
else
{
      $orderby='newstime';
}
//是否有历史记录
if($searchid)
{
    $search_num=$empire->gettotal($query);
      $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'");
      if(empty($search_num))
      {
                $searchid=0;
      }
}
else
{
      $search_num=$empire->gettotal($query);
      if(empty($search_num))
      {
                $searchid=0;
      }
      else
      {
                $iskey=$keyboardone==1?0:1;
                $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')");
                $searchid=$empire->lastid();
      }
}
//设置最后搜索时间
$set1=esetcookie("lastsearchtime",$searchtime,$searchtime+3600*24);
if(!$searchid)
{
      printerror("SearchNotRecord",$getfrom,1);
}
else
{
      Header("Location:result/?searchid=$searchid".$dogetvar);
}
db_close();
$empire=null;
?>

如果你的搜索做过 帝国CMS搜索结果关键字高亮
请使用一下方法替代
修改e/search/result/index.php
找到$changerow+=1;
在这句代码的前面加上代码:
$listtext = keyboardHighlight($search_r['keyboard'], $listtext); // 搜索关键词高亮
在页面中加入下面函数
// 关键字都加高亮
function keyboardHighlight($keyboard, $listtext){
      $arr = explode(' ', $keyboard);
      $newArr = array_map(function ($item){
            return '<em>' . $item . '</em>';
      }, $arr);
      return str_replace($arr, $newArr, $listtext);
}

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


页: [1]
查看完整版本: 帝国CMS搜索优化(支持多关键字词空格搜索结果)