1. 程式人生 > >PHP搜尋功能的實現 (2)( 匹配)

PHP搜尋功能的實現 (2)( 匹配)

整體匹配思路:
利用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));
    }