/** * 数据处理 * @param type $data 数据 * @return type */ private function dataHandle($data, $text = '') { if (!$data) { return $data; } import("Input"); $data = addslashes($data); $data = strip_tags($data); $data = str_replace(array(" ", "\r\t"), array(""), $data); $data = Input::forSearch($data); $data = Input::deleteHtmlTags($data); $config = F("Search_config"); if (!$config) { $this->search_cache(); $config = F("Search_config"); } //判断是否启用sphinx全文索引,如果不是,则进行php简易分词处理 if ((int) $config['sphinxenable'] == 0 && $config['segment']) { static $Segment; if (!isset($Segment)) { import("Segment", APP_PATH . C("APP_GROUP_PATH") . '/Search/Class/'); $Segment = new Segment(); } $fulltext_data = $Segment->get_keyword($Segment->split_result($data)); $data = $text . $fulltext_data; } return $data; }
public function index() { C('TOKEN_ON', false); $seo = seo(); $this->assign("seo", $seo); if (isset($_GET['q'])) { G('search'); //关键字 $q = Input::forSearch(safe_replace($this->_get("q"))); $q = htmlspecialchars(strip_tags($q)); //时间范围 $time = $this->_get("time"); //模型 $mid = (int) $this->_get("modelid"); //栏目 $catid = (int) $this->_get("catid"); //排序 $order = array("adddate" => "DESC", "searchid" => "DESC"); //搜索历史记录 $shistory = cookie("shistory"); if (!$shistory) { $shistory = array(); } $model = F("Model"); $category = F("Category"); if (trim($_GET['q']) == '') { header('Location: ' . U("Search/Index/index")); exit; } array_unshift($shistory, $q); $shistory = array_slice(array_unique($shistory), 0, 10); //加入搜索历史 cookie("shistory", $shistory); $where = array(); //每页显示条数 $pagesize = $this->config['pagesize'] ? $this->config['pagesize'] : 10; //缓存时间 $cachetime = (int) $this->config['cachetime']; //按时间搜索 if ($time == 'day') { //一天 $search_time = time() - 86400; $where['adddate'] = array("GT", $search_time); } elseif ($time == 'week') { //一周 $search_time = time() - 604800; $where['adddate'] = array("GT", $search_time); } elseif ($time == 'month') { //一月 $search_time = time() - 2592000; $where['adddate'] = array("GT", $search_time); } elseif ($time == 'year') { //一年 $search_time = time() - 31536000; $where['adddate'] = array("GT", $search_time); } else { $search_time = 0; } //可用数据源 $this->config['modelid'] = $this->config['modelid'] ? $this->config['modelid'] : array(); //按模型搜索 if ($mid && in_array($mid, $this->config['modelid'])) { $where['modelid'] = array("EQ", (int) $mid); } //按栏目搜索 if ($catid) { //不支持多栏目搜索,和父栏目搜索。 $where['catid'] = array("EQ", (int) $catid); } //分页模板 $TP = '共有{recordcount}条信息 {pageindex}/{pagecount} {first}{prev}{liststart}{list}{listend}{next}{last}'; //如果开启sphinx if ($this->config['sphinxenable']) { import("Sphinxapi", APP_PATH . C("APP_GROUP_PATH") . '/Search/Class/'); $sphinxhost = $this->config['sphinxhost']; $sphinxport = $this->config['sphinxport']; $cl = new SphinxClient(); //设置searchd的主机名和TCP端口 $cl->SetServer($sphinxhost, $sphinxport); //设置连接超时 $cl->SetConnectTimeout(1); //控制搜索结果集的返回格式 $cl->SetArrayResult(true); //设置全文查询的匹配模式 api http://docs.php.net/manual/zh/sphinxclient.setmatchmode.php $cl->SetMatchMode(SPH_MATCH_EXTENDED2); //设置排名模式 api http://docs.php.net/manual/zh/sphinxclient.setrankingmode.php $cl->SetRankingMode(SPH_RANK_PROXIMITY_BM25); //按一种类似SQL的方式将列组合起来,升序或降序排列。用weight是权重排序 $cl->SetSortMode(SPH_SORT_EXTENDED, "@weight desc"); //设置返回结果集偏移量和数目 $page = (int) $this->_get(C("VAR_PAGE")); $page = $page < 1 ? 1 : $page; $offset = $pagesize * ($page - 1); $cl->SetLimits($offset, $pagesize, $pagesize > 1000 ? $pagesize : 1000); if (in_array($time, array("day", "week", "month", "year"))) { //过滤时间 $cl->SetFilterRange('adddate', $search_time, time(), false); } if ($mid && in_array($mid, $this->config['modelid'])) { //过滤模型 $cl->SetFilter('modelid', (int) $mid); } if ($catid) { //过滤栏目 $cl->SetFilter('catid', (int) $catid); } //执行搜索 api http://docs.php.net/manual/zh/sphinxclient.query.php $res = $cl->Query($q, "*"); //信息总数 $count = $res['total']; //如果结果不为空 if (!empty($res['matches'])) { $result_sphinx = $res['matches']; } $result = array(); //数组重新组合 foreach ($result_sphinx as $k => $v) { $result[$k] = array("searchid" => $v['id'], "adddate" => $v['attrs']['adddate'], "catid" => $v['attrs']['catid'], "id" => $v['attrs']['id'], "modelid" => $v['attrs']['modelid']); } $words = array(); //搜索关键字 foreach ($res['words'] as $k => $v) { $words[] = $k; } $page = page($count, $pagesize); $page->SetPager('default', $TP, array("listlong" => "6", "first" => "首页", "last" => "尾页", "prev" => "上一页", "next" => "下一页", "list" => "*", "disabledclass" => "")); $this->assign("Page", $page->show('default')); } else { import("Segment", APP_PATH . C("APP_GROUP_PATH") . '/Search/Class/'); $Segment = new Segment(); //分词结果 $segment_q = $Segment->get_keyword($Segment->split_result($q)); $words = explode(" ", $segment_q); if (!empty($segment_q)) { $where['_string'] = " MATCH (`data`) AGAINST ('{$segment_q}' IN BOOLEAN MODE) "; } else { //这种搜索最不行 $where['data'] = array('like', "%{$q}%"); } //查询结果缓存 if ($cachetime) { //统计 $count = M("Search")->cache(true, $cachetime)->where($where)->count(); $page = page($count, $pagesize); $result = M("Search")->cache(true, $cachetime)->where($where)->limit($page->firstRow . ',' . $page->listRows)->order($order)->select(); } else { $count = M("Search")->where($where)->count(); $page = $this->page($count, $pagesize); $result = M("Search")->where($where)->limit($page->firstRow . ',' . $page->listRows)->order($order)->select(); } $page->SetPager('default', $TP, array("listlong" => "6", "first" => "首页", "last" => "尾页", "prev" => "上一页", "next" => "下一页", "list" => "*", "disabledclass" => "")); $this->assign("Page", $page->show('default')); } //搜索结果处理 if ($result && is_array($result)) { foreach ($result as $k => $r) { $modelid = $r['modelid']; $id = $r['id']; $tablename = ucwords($model[$modelid]['tablename']); if ($tablename) { $result[$k] = M($tablename)->where(array("id" => $id))->find(); } } } //搜索记录 if (strlen($q) < 17 && strlen($q) > 1 && $result) { $res = M("SearchKeyword")->where(array('keyword' => $q))->find(); if ($res) { //关键词搜索数+1 M("SearchKeyword")->where(array('keyword' => $q))->setInc("searchnums"); } else { //关键词转换为拼音 load("@.iconvfunc"); $pinyin = gbk_to_pinyin(iconv('utf-8', 'gbk//IGNORE', $q)); if (is_array($pinyin)) { $pinyin = implode('', $pinyin); } M("SearchKeyword")->add(array('keyword' => $q, 'searchnums' => 1, 'data' => $segment_q, 'pinyin' => $pinyin)); } } //相关搜索功能 if ($this->config['relationenble']) { $map = array(); //相关搜索 if (!empty($segment_q)) { $relation_q = str_replace(' ', '%', $segment_q); } else { $relation_q = $q; } $map['_string'] = " MATCH (`data`) AGAINST ('%{$relation_q}%' IN BOOLEAN MODE) "; $relation = M("SearchKeyword")->where($map)->select(); $this->assign("relation", $relation); } foreach ($this->config['modelid'] as $modelid) { $source[$modelid] = array("name" => $model[$modelid]['name'], "modelid" => $modelid); } //搜索结果 $this->assign("result", $result); //运行时间 $search_time = G('search', 'end', 6); $this->assign("count", $count ? $count : 0); $this->assign("search_time", $search_time); $this->assign("keyword", $q); $this->assign("category", $category); $this->assign("source", $source); $this->assign("time", $time); $this->assign("modelid", $mid); $this->assign("shistory", $shistory); //分词后的搜索关键字 $this->assign("words", $words); $this->display("search"); } else { $this->display(); } }