什么是搜索?
在一堆数据里通过查询条件筛选出你想要的结果。
所以其实分页、标签、关键词、归档都叫搜索。
搜索分两部分:组装搜索条件、将搜索结果如实的反应在页面上即告诉用户我当前搜索的条件是什么,不要让用户只能通过url判断。
而在TP中。搜索的实现就是体现在怎么根据get或者post参数,动态生成一个查询条件数组。
## 标签tag搜索
~~~
//tag搜索
$tags = I('get.tag');
if($tags){
$ids = $postModel->where("FIND_IN_SET('{$tags}',tags)")->getField('id', true);
$this->assign('title', "标签 <i>{$tags}</i> 下的文章");
if(!empty($ids))
$map['id'] = array('in',$ids);
}
~~~
标签搜索,我把他分解为搜素符合标签的id再通过 id in去筛选。
为什么不把FIND_IN_SET 放到map中?
首先,tp里只能用`_string` 用法来实现 字段中带函数的使用,但是后面归档也用了_string 防止以后还有这种情况,可能会造成冲突。干脆查出id,反正只有这种情况是子查询,查询结果也快。
然后,tag搜索虽然来自表签的点击,但是可以通过url伪造。分开写,不容易出安全问题。
find_in_set 是mysql 专门为以一个分隔符拼接多个值存一个字段时搜索提供的函数。
以往我们面对 1,2,3 这样的 只能 最后也加一个',' 变成1,2,3, 这样like "%$a,%" 这样hack的方式去搜索。
## 关键词搜索
//关键词搜搜
~~~
if(I('get.kw')){
$kw = trim(I('get.kw'));
$search = array();
$search['title'] = array('like', '%{$kw}%');
$like_id = $postModel->where("content LIKE '%{$kw}%' OR description LIKE '%{$kw}%'")->getField('id', true);
if($like_id)
$search['id'] = array('in', $like_id);
$search['_logic'] = 'or';
$map['_complex'] = $search;
}
~~~
搜索关键词,我们也分开搜索。匹配模糊查询content和description2个长文本字符串的文章id和匹配模糊查询的title。然后由于这2个条件是OR 或的关系,整个查询where 部分语句和其他的条件又是and 且的关系。所以我用了_complex来实现这个搜索。
由于我们只是演示功能如何实现,性能不是我们目前该考虑的。搜索慢的时候再去考虑要不要做全文检索。
关键词搜索,分开了以后也有机会做查询缓存。这样什么关键词匹配什么id。
不过以后可能考虑的是这个缓存怎么做。因为关键词搜索后面还要考虑全部数据搜索和当前用的搜索行为。
然后,搜索我们url “/Search?kw=关键词” 我们也分配了一个search方法:
~~~
//搜索
public function search(){
$kw = I('get.kw');
if(!$kw)
$this->error('请输入关键字');
$this->assign('title', "包含关键字 {$kw} 的文章");
$this->assign('kw', $kw);
$this->lists(I('get.page', 1));
$this->display('Index/index');
}
~~~
处理了关键词为空的错误提示,和搜索时标题。
刚刚标签我们没有分配一个方法给它,而是在lists里指定了title。这样做是标签以后可能在其他地方符合搜索,比如我的空间里某个标签的文章。
就是 mine.html?tag=音乐 这样也支持。
这样如要要这个功能,我们只需要改前台生成标签的函数,和sidebar侧边栏上的全部热门标签那块。
如果要那么做,全部热门标签也得区分首页和个人的了,如果考虑别人空间的,也得显示为“XXX的热门标签”。
暂时先这么做。标签都是通用搜索。url上不特殊处理。知道以后很容易支持就好了。
- 序
- 前言
- 内容简介
- 目录
- 基础知识
- 起步
- 控制器
- 模型
- 模板
- 命名空间
- 进阶知识
- 路由
- 配置
- 缓存
- 权限
- 扩展
- 国际化
- 安全
- 单元测试
- 拿来主义
- 调试方法
- 调试的步骤
- 调试工具
- 显示trace信息
- 开启调试和关闭调试的区别
- netbeans+xdebug
- Socketlog
- PHP常见错误
- 小黄鸭调试法,每个程序员都要知道的
- 应用场景
- 第三方登录
- 图片处理
- 博客
- SAE
- REST实践
- Cli
- ajax分页
- barcode条形码
- excel
- 发邮件
- 汉字转全拼和首字母,支持带声调
- 中文分词
- 浏览器useragent解析
- freelog项目实战
- 需求分析
- 数据库设计
- 编码实践
- 前端实现
- rest接口
- 文章发布
- 文件上传
- 视频播放
- 音乐播放
- 图片幻灯片展示
- 注册和登录
- 个人资料更新
- 第三方登录的使用
- 后台
- 微信的开发
- 首页及个人主页
- 列表
- 归档
- 搜索
- 分页
- 总结经验
- 自我提升
- 进行小项目的锻炼
- 对现有轮子的重构和移植
- 写技术博客
- 制作视频教程
- 学习PHP的知识和新特性
- 和同行直接沟通、交流
- 学好英语,走向国际
- 如何参与
- 浏览官网和极思维还有看云
- 回答ThinkPHP新手的问题
- 尝试发现ThinkPHP的bug,告诉官方人员或者push request
- 开发能提高效率的ThinkPHP工具
- 尝试翻译官方文档
- 帮新手入门
- 创造基于ThinkPHP的产品,进行连带推广
- 展望未来
- OneThink
- ThinkPHP4
- 附录