首頁  >  文章  >  php框架  >  ThinkPHP:模型三大利器之一(搜尋器)

ThinkPHP:模型三大利器之一(搜尋器)

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼轉載
2019-12-16 16:51:503201瀏覽

ThinkPHP:模型三大利器之一(搜尋器)

[√新技能] 搜尋器-統一管理你的搜尋代碼

模型搜尋器是自模型獲取器和修改器功能之後的第三個統一管理的利器,主要用於封裝字段(或搜尋標識)的查詢條件表達式,一個搜尋器對應一個特殊的方法(該方法必須是public類型),方法命名規格為:searchFieldNameAttr(FieldName為資料表欄位的駝峰轉換),搜尋器僅在呼叫withSearch方法的時候觸發。

搜尋器的使用情境包括:

    ·限制與規格表單的搜尋條件;

#    ·#預先定義查詢條件簡化查詢。

例如,我們需要為User模型定義name欄位和時間欄位的搜尋器,可以使用:

<?php
namespace app\index\model;
use think\Model;
class User extends Model 
{
    public function searchNameAttr($query, $value, $data)
    {
        $query->where(&#39;name&#39;,&#39;like&#39;, $value . &#39;%&#39;);
    }
    
    public function searchCreateTimeAttr($query, $value, $data)
    {
        $query->whereBetweenTime(&#39;create_time&#39;, $value[0], $value[1]);
    }    
}

搜尋器方法的參數有三個,第一個是查詢對象,第二個是目前搜尋標識的值,第三個是目前所有的搜尋資料(可選)。

然後,我們可以使用下面的查詢

User::withSearch([&#39;name&#39;, &#39;create_time&#39;], [
&#39;name&#39;=>&#39;think&#39;,
    &#39;create_time&#39;=>[&#39;2018-8-1&#39;,&#39;2018-8-5&#39;],
        &#39;status&#39;=>1
    ])
->select();

最終產生的SQL語句類似於

SELECT * FROM `think_user` WHERE  `name` LIKE &#39;think%&#39; AND `create_time` BETWEEN &#39;2018-08-01 00:00:00&#39; AND 
&#39;2018-08-05 00:00:00&#39;

可以看到查詢條件中並沒有status欄位的數據,因此可以很好的避免表單的非法查詢條件傳入,在這個範例中只能使用name和create_time條件來查詢。

事實上,除了在搜尋器中使用查詢表達式外,還可以使用其它的任何查詢建構器以及鍊式操作。

例如,你需要透過表單定義的排序欄位進行搜尋結果的排序,可以使用

<?php
namespace app\index\model;
use think\Model;
class User extends Model 
{
    public function searchNameAttr($query, $value, $data)
    {
        $query->where(&#39;name&#39;,&#39;like&#39;, $value . &#39;%&#39;);
        if (isset($data[&#39;sort&#39;])) {
        $query->order($data[&#39;sort&#39;]);
        }        
    }
    
    public function searchCreateTimeAttr($query, $value, $data)
    {
        $query->whereBetweenTime(&#39;create_time&#39;, $value[0], $value[1]);
    }      
}

然後,我們可以使用下面的查詢

User::withSearch([&#39;name&#39;,&#39;create_time&#39;, &#39;status&#39;], [
&#39;name&#39;=>&#39;think&#39;,
    &#39;create_time&#39;=>[&#39;2018-8-1&#39;,&#39;2018-8-5&#39;],
        &#39;status&#39;=>1,
        &#39;sort&#39;=>[&#39;status&#39;=>&#39;desc&#39;],
    ])
->select();

最終查詢的SQL可能是

SELECT * FROM `think_user` WHERE  `name` LIKE &#39;think%&#39; AND `create_time` BETWEEN &#39;2018-08-01 00:00:00&#39; AND 
&#39;2018-08-05 00:00:00&#39; ORDER BY `status` DESC

你也可以給搜尋器定義欄位別名,例如:

User::withSearch([&#39;name&#39; => &#39;nickname&#39;,&#39;create_time&#39;, &#39;status&#39;], [
&#39;nickname&#39;=>&#39;think&#39;,
    &#39;create_time&#39;=>[&#39;2018-8-1&#39;,&#39;2018-8-5&#39;],
        &#39;status&#39;=>1,
        &#39;sort&#39;=>[&#39;status&#39;=>&#39;desc&#39;],
    ])
->select();

搜尋的資料使用的是nickname欄位標識,但我們仍然使用的是name欄位標識的搜尋器(也就是searchNameAttr方法)。

搜尋器通常會和查詢範圍進行比較,搜尋器無論定義了多少,只需要一次調用,查詢範圍如果需要組合查詢的時候就需要多次調用。

如果你使用的是Db查詢方法,仍然可以使用搜尋器功能,只是搜尋器方法定義需要改成閉包方式,如下:

User::withSearch([&#39;name&#39; => function($query,$value,$data){
    $query->where(&#39;name&#39;,&#39;like&#39;, $value . &#39;%&#39;);
}, &#39;create_time&#39;=>function($query,$value,$data){
    $query->whereBetweenTime(&#39;create_time&#39;, $value[0], $value[1]);
}], [
&#39;name&#39;=>&#39;think&#39;,
    &#39;create_time&#39;=>[&#39;2018-8-1&#39;,&#39;2018-8-5&#39;],
        &#39;status&#39;=>1
    ])
->select();

PHP中文網,有大量免費的ThinkPHP入門教學,歡迎大家來學習!

本文轉自:https://blog.thinkphp.cn/783775

以上是ThinkPHP:模型三大利器之一(搜尋器)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:thinkphp.cn。如有侵權,請聯絡admin@php.cn刪除