什么是搜索?
在一堆數據里通過查詢條件篩選出你想要的結果。
所以其實分頁、標簽、關鍵詞、歸檔都叫搜索。
搜索分兩部分:組裝搜索條件、將搜索結果如實的反應在頁面上即告訴用戶我當前搜索的條件是什么,不要讓用戶只能通過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
- 附錄