最近開發碰到個問題,在把資料寫入快取時候,我們得到的是stdclass,寫入後只能 ToArray()
,轉 json
存入。
那麼當我們讀取的時候呢?
你傳給變數,但是!重要的來了,你這個變數之前是stdclass,是具有 laravel orm
的模型屬性的!
那我們怎麼辦呢?
請看下文。
setRawAttributes 介紹
setRawAttributes 函式為新的資料庫物件賦予屬性值,並且進行 sync,標誌著物件的原始狀態:
public function setRawAttributes(array $attributes, $sync = false)
{
$this->attributes = $attributes;
if ($sync) {
$this->syncOriginal();
}
return $this;
}
public function syncOriginal()
{
$this->original = $this->attributes;
return $this;
}
這個原始狀態的記錄十分重要,原因是 save 函式就是利用原始值 original 與屬性值 attributes 的差異來決定更新的欄位。
下面貼我的程式碼片段
// 讀取快取
$cacheData = $redisWarp->readCache($cacheName,$redis);
if ( !empty($cacheData) )
{
$result = collect();
// 遍歷填充model 屬性
foreach($cacheData as $m)
{
$model = app(Article::class);
BaseCacheTrait::fillModel( $model, $m );
$result->push($model);
}
return $result;
}
是如何填充屬性的?
下面我們進入 BaseCacheTrait::fillModel( $model, $m );
中來看這個 是如何填充屬性的?
/**
* 初始化model,使其能正常使用save等操作
*
* @param Object $model
* @param array $attrs
* @return Object
*/
static public function fillModel($model, $attrs=[])
{
//這裡必須使用內建函式賦值,否則外面使用save函式時,會將改動的都進行insert操作導致失敗
//也可以使用 newFromBuilder 方法重新建立一個
if ( !empty($attrs) )
{
$model->setRawAttributes($attrs,true);
}
else
{
//如果沒有傳入 屬性陣列,外部需要保證自己有進行過資料初始化,
//這裡只是對資料進行同步處理
$model->syncOriginal();
}
//$model->forceFill($cache_data);
//需要將此屬性設定為true,便於外部使用時使用save 操作時能進行更新
$model->exists = true;
return $model;
}