天天看點

TP5擷取器

前言:

tp5中有個小功能,在文檔中介紹的不多,卻非常實用,在其他地方它叫讀取器。tp5中它叫擷取器。如果單看文檔我也覺得有些雲裡霧裡,好像懂了又好像沒懂。下面我們結合實際應用場景來看看這個擷取器的應用。

應用一:

當我們在資料庫中儲存一張圖檔的路徑時。我們一般會選擇儲存相對路徑,因為相對路徑更加靈活。如果在後端渲染視圖時,直接使用相對路徑也沒有問題。可是當我們應用到接口開發中,我們傳回客戶單需要傳回完整的帶域名的路徑。這個時候,我們不能在每次傳回的時候,都去添加上域名。這樣就非常的麻煩。下面來看看擷取器如何解決這個問題。

首先我交代下資料表結構:除了表中儲存圖檔的字段url,還有一個字段from,這個from就代表是否存在自己的伺服器上,如果是1,則存儲的是相對路徑,而from等于别的數字,則代表存儲在别的伺服器上,存儲的是絕對路徑

然後我們将需求分解

第一我們将圖檔url傳回到用戶端時//TODO

第二是将url加上域名

我們認為,給url加上域名這個操作是比較容易複現的。

是以我們講這個操作封裝到基類之中

class BaseModel extends Model
{

    /**
     * 拼接web域名,根據傳入$data中的from判斷儲存狀況.自動傳回url
     * @param $value 存儲的url
     * @param $data  目前url所屬的整條資料
     * @return string
     */
    protected function splicingPrefix($value, $data)
    {
        //如果from的值等于1則說明是存在自己的伺服器裡的,也就是存的相對路徑
        //如果不為1,則是存在cnd或别的伺服器上,就是存的絕對路徑,就不做任何修改
        return $data['from'] == 1 ? (config('setting.url_prefix') . $value) : $value;
    }

}
           
中間使用了config助手函數,我将自己的域名放在配置中,友善以後換域名等。

那麼現在問題是,這個拼接方法很簡單,可是,$value,$data這兩個參數是哪裡來的。

這時候就該看看我們擷取器的用法了。
  1. 首先擷取器是寫在Model層的,而且要繼承自tp的model類
  2. 擷取器方法名是一個固定的寫法 (get駝峰寫法的字段名Attr)比如 getUrlAttr
  3. 擷取器會自動接收兩個參數,一是讀取字段的值,二傳入的是目前的所有資料數組
class Image extends BaseModel
{
    protected $visible = ['url'];

    /**
     * 讀取器,在讀取的時候觸發,調用基類中的拼接web域名方法
     * @param $value
     * @param $data
     * @return string
     */
    public function getUrlAttr($value, $data)
    {
        return $this->splicingPrefix($value,$data);
    }
}
           

這樣我們tp注入的兩個參數拿去調用模型基類中的拼接域名方法。

那麼當讀取到url這個參數時,首先會觸發擷取器,擷取器會接受$value,$data兩個參數,拿到這兩個參數後,會到模型基類中去調用拼接域名方法,然後傳回,傳回到擷取器方法之後,擷取器又将結果傳回。

這樣我們在讀取url時,讀取的就是一個已經被處理過的完整的url了

應用二:

有時候,我們會将資料庫中某一個字段來存儲一些序列化後的數組。雖然這樣做并不太好。但是确實有需求,我們在查資料反回給用戶端時,需要反序列化下。如果每次查這條資料的時候都去手動反序列化,就不太友善。

我們看看擷取器是如何幫助我們搞定的

我這裡就拿位址位址來做比方,我講位址資料儲存在數組中,序列化後存在資料庫

在對應的model層中,建構擷取器。

public function getSnapAddressAttr($value)
    {
        if (empty($value)) {
            return null;
        }
        return unserialize($value);
    }
           

這樣,在讀取位址字段時候,就會自動的反序列化成一個數組。

好啦今天就介紹到這裡,比較簡單的用法,主要是開闊下思路。