TP5獲取器

勃起狂奔者發表於2018-03-07

前言:

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);
    }

這樣,在讀取地址欄位時候,就會自動的反序列化成一個陣列。

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


相關文章