PHP搜尋功能的實現 (2)( 匹配)
阿新 • • 發佈:2019-01-27
整體匹配思路:
利用match與against進行全文匹配,
整體程式碼:
public $max_results = 100; // 搜尋結果超過這個數值, 超過的部分將被拋棄
public function search_call($q,$page = 1, $limit = 20)
{
//where陣列整合成where語句
if ($where)
{
$where = implode(' AND ', $where);
}
//get_search_hash獲取SQL語句的md5碼(詳見後面)
$search_hash = $this->get_search_hash('con_notice', 'all_name', $q, $where);
//如果從快取中找不到,再去資料庫中查詢
if (!$result = $this->fetch_cache($search_hash))
{
if ($result = $this->query_all($this->bulid_query('con_notice', 'all_name', $q, $where), $this ->max_results))
{
//按照匹配值的得分進行排序(score來自後面的build_query產生SQL語句的結果)
$result = aasort($result, 'score', 'DESC');
}
else
{
return false;
}
//儲存快取
$this->save_cache($search_hash , $result);
}
if (!$page)
{
$slice_offset = 0;
}
else
{
$slice_offset = (($page - 1) * $limit);
}
//返回結果(array_slice用於擷取結果)
return array_slice($result, $slice_offset, $limit);
}
- get_search_hash(獲取SQL語句的md5碼)
public function get_search_hash($table, $column, $q, $where = null)
{
return md5($this->bulid_query($table, $column, $q, $where));
}
- bulid_query(構造查詢的SQL 語句)
public function bulid_query($table, $column, $q, $where = null)
{
if (is_array($q))
{
$q = implode(' ', $q);
}
//對使用者輸入的語句 進行分詞處理
if ($analysis_keyword = $this->model('system')->analysis_keyword($q))
{
$keyword = implode(' ', $analysis_keyword);
}
else
{
$keyword = $q;
}
if ($where)
{
$where = ' AND (' . $where . ')';
}
$search_string=$this->quote($keyword);
//構造成SQL語句
return trim("SELECT *, MATCH(" . $column . "_fulltext) AGAINST('" . $search_string. "') AS score FROM " . $this->get_table($table) . " WHERE MATCH(" . $column . "_fulltext) AGAINST('" . $search_string . "')" . $where);
}
- fetch_cache(從快取中查詢結果)
public function fetch_cache($search_hash)
{
if ($search_cache = $this->fetch_row('search_cache', "`hash` = '" . $this->quote($search_hash) . "'"))
{
//利用gzuncompress base64_decode 進行資料壓縮(詳見我的下一篇文章)
return unserialize(gzuncompress(base64_decode($search_cache['data'])));
}
}
/**
* 新增引號防止資料庫攻擊
*
* 外部提交的資料需要使用此方法進行清理
*
* @param string
* @return string
*/
public function quote($string)
{
if (is_object($this->db()))
{
$_quote = $this->db()->quote($string);
if (substr($_quote, 0, 1) == "'")
{
$_quote = substr(substr($_quote, 1), 0, -1);
}
return $_quote;
}
if (function_exists('mysql_escape_string'))
{
$string = @mysql_escape_string($string);
}
else
{
$string = addslashes($string);
}
return $string;
}
- save_cache儲存快取
- remove_cache 刪除快取
- clean_cache 清理快取(根據時間)
public function save_cache($search_hash, $data)
{
if (!$data)
{
return false;
}
if ($this->fetch_cache($search_hash))
{
$this->remove_cache($search_hash);
}
return $this->insert('search_cache', array(
'hash' => $search_hash,
'data' => base64_encode(gzcompress(serialize($data))),
'time' => time()
));
}
public function remove_cache($search_hash)
{
return $this->delete('search_cache', "`hash` = '" . $this->quote($search_hash) . "'");
}
public function clean_cache()
{
return $this->delete('search_cache', 'time < ' . (time() - 900));
}