這次給大家帶來Laravel ORM對Model::find緩衝方法詳解,Laravel ORM對Model::find緩衝的注意事項有哪些,下面就是實戰案例,一起來看一下。
前言
前段時間做項目時候,想要在不改變方法簽名的情況下,給 Model::find 方法做個緩衝。而且想要做到隨插即用。下面話不多說了,來一起看看詳細的介紹哦。
1.先看一下當我們調用 find 方法時,架構幹了什嗎?
找到 Illuminate\Database\Eloquent\Model 的代碼,搜尋 find,沒有該方法。看來是走了 callStatic 這個魔術方法。該方法裡只有一行代碼:
return (new static)->$method(...$parameters);
static 指的是調用該靜態方法的類(如果使用的是 UserModel::find(1),則 static 就代表 UserModel 類)。看來是執行個體化了一個對象,並調用了成員方法。
2.分析如何優雅地在中間插一腳
為了能夠在調用 find 時候,先走我們的緩衝,所以我們需要覆蓋 callStatic 方法,並檢測如果是 find 方法,則優先返回緩衝中的資料。
另外,為了能夠達到隨插即用的效果,我們使用繼承的方式,而是使用了 Trait。核心邏輯如下:
public static function create($data = null){ if ($data == null){ return null; } $instance = new static; foreach ($data as $key => $value){ $instance[$key] = $value; } return $instance;}/** * 如果方法是 find($id, $nocache) * * @param string $method * @param array $parameters * @return mixed */public static function callStatic($method, $parameters){ if ($method == 'find'){ // 從緩衝中擷取資料 $obj = static::create(json_decode(Redis::get(static::getCacheKey($parameters[0])), true)); if (null == $obj){ $obj = (new static)->$method(...$parameters); if (null == $obj){ return null; } else { $key = static::getCacheKey($parameters[0]); // 設定緩衝及到期時間 Redis::set($key, $obj); Redis::expire($key, static::$expire_time); return $obj; } } else { $obj->exists = true; return $obj; } } else if($method == 'findNoCache'){ $method = 'find'; return (new static)->$method(...$parameters); } return (new static)->$method(...$parameters);}private static function getCacheKey($id){ $name = str_replace('\\', ':', CLASS); return "{$name}:{$id}";}
大體邏輯上面已經介紹過了:覆蓋 callStatic 方法,判斷如果是調用 find ,則走緩衝(無緩衝,查詢後需要設定緩衝)。另新增 findNoCache 方法。
3.細節補充
當修改(或刪除)資料(調用 save 方法)時需要刪除已緩衝的內容。
private static function clearCache($id){ Redis::del(self::getCacheKey($id));}/** * when save, should clear cache * @param array $options */public function save(array $options = []){ static::clearCache($this[$this->primaryKey]); return parent::save($options);}// delete 方法我暫時寫,內容類別似 save 方法
如何使用。在需要使用 find 緩衝的 Model 類裡,加上一行就夠了。
class User extends BaseModel{ use MemoryCacheTrait;}
快去試試吧。
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
PHP動態刪除XML資料步驟詳解
Mac系統內安裝PHP Xdebug步驟詳解