作为许久未开贴的萌新,在踏入PHP领域后刚刚工作个月,虚的很,一直没有开张,这次借着一个项目中的启发分享一下针对限制在数据库中模糊匹配而实现模糊搜索的一些思路。PHP自然会接触许多网页列表展示的页面需求,比如一个搜索框带分页的List展示,有时候我们需要实现搜索框输入个别关键字而找到数据库表中存在的全部完整条目。
一. 两轮模糊匹配,做分页取数据
既然无法在数据库中模糊查询,我们第一反应就是把数据先从数据库取出来,再在外面对数据进行模糊匹配处理即可。不过由于我们的项目需要制作分页,那么这样处理的数据很明显和分页是匹配不上的。不过这个时候我们需要解决的问题也就很明朗了,计算出准确的分页数。
那我们可以先取出数据库所有需要匹配的数据,与文本填入的关键词首先进行模糊匹配,对每个关键词匹配出来的所有完整广告主题都进行分页的计算,最后累加即为总分页数,这样我们就获得了正确的分页数展现在页面上。
二. 利用搜索下拉提示框
现在任何搜索引擎都会在你输入的时候出现提示下拉框,你只要选中相关内容即可实现搜索,这对用户体验也有很大的提升。我们也可以借助这种模式,输入关键词的时候通过异步调用监听输入的关键词,将数据库中所有需要匹配的数据提取到后台或者页面与输入的关键词做匹配筛选。其实如果数据库中数据量不大针对业务我们可以很粗暴的使用一些插件直接取出所有数据到插件下拉框内,只要符合插件规则即可实现效果。在项目中我也是两种方法合并到一起使用,对用户体验和效果都有兼顾。
部分示例代码如下(自己重写的伪代码,非项目原代码):
//获取数据库所有rb_title数据
$title = x::getInstance()->getList(['rb_id' => ['gt', 0]], 'rb_title');
//拼接自动下拉框插件要求字符串
$title_all = (array_column($title, 'rb_title'));
foreach ($title_all as $key => $value) {
$title_all .= '"' . $value . '",';
}
$title_all = str_replace('Array', '', $title_all);
$title_all = '[' . trim($title_all, ',') . ']';
$this->assign('title_all', $title_all);
//进行主题的模糊匹配
$rb_title = I('get._title');
$title_data = y->getTitleMatch($rb_title, $title);
$title_data = array_column($title_data, 'rb_title');
//获取计算分页数据的条件
$where = y->getWhere($status, $rb_title, $title_data);
//计算出分页数量
if (count($where) > 1) {
//当关键字匹配多条查询结果时
//数据总数
$Max = 0;
foreach ($where as $key => $value) {
$max[$key] = x::getInstance()->getCount($value);
}
foreach ($max as $key => $value) {
$Max = $value + $Max;
}
import('@.ORG.Page');
//获取分页数
$page = new Page($Max, 15);
$limit = $page->firstRow . ',' . $page->listRows;
} else {
$max = x::getInstance()->getCount($where);
import('@.ORG.Page');
$page = new Page($max, 15);
$limit = $page->firstRow . ',' . $page->listRows;
}
//模糊匹配函数
public function getTitleMatch($rb_title, $_data)
{
$count = (mb_strlen($rb_title));
foreach ($_data as $key => $value) {
if (strpos($_data[$key]['rb_title'], $rb_title) != false) {
$_match[] = $_data[$key];
}
if ($rb_title == mb_substr($_data[$key]['rb_title'], 0, $count)) {
$_match[] = $_data[$key];
}
}
return $_match;
}
///bootstrap/js/bootstrap.min.js插件使用
html的input上附加上:
autocomplete="off" data-provide="typeahead" data-source='{$title_all}'
这里做的虽然只是后台一个小小的搜索功能。甚至对数据量以及内容都没有很显著的要求。但是倘若一次检索获取成千上万条数据,我们如何筛选数据进行分页上的排序呢?下一期会和大家分享查询的相关性方法,请期待!