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));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值