在laravel中,fill方法是一個給Eloquent範例賦值屬性的方法,該方法可以理解為用於過濾前端傳輸過來的與模型中對應的多餘欄位;當呼叫該方法時,會先去檢測當前Model的狀態,根據fillable陣列的設定,Model會處於不同的狀態。
本文操作環境:Windows10系統、Laravel6版、Dell G3電腦。
fill 方法是一個給 Eloquent 範例賦值屬性的方法,
讓咱們點開 fill 方法先看一看它的原始碼:陣列
這裡筆者所使用的版本為 Laravel 5.5最新版,為了方便閱讀,刪除掉了註釋框架
public function fill(array $attributes) { $totallyGuarded = $this->totallyGuarded(); foreach ($this->fillableFromArray($attributes) as $key => $value) { $key = $this->removeTableFromKey($key); if ($this->isFillable($key)) { $this->setAttribute($key, $value); } elseif ($totallyGuarded) { throw new MassAssignmentException($key); } } return $this; }
首先能夠看到,Laravel 會先去呼叫一個自身的 totallyGuarded 方法,讓咱們點開這個方法:函數
public function totallyGuarded() { return count($this->getFillable()) == 0 && $this->getGuarded() == ['*']; }
能夠看到這個方法的做用就是去獲取自身的 fillable 與 guarded,而後判斷他們是否都為 不可批次賦值 狀態,最後返回一個布林值this
// 返回一個 True or False 的布林值 // 若是未設定 fillable 與 guarded,則會返回 True (注意,在這種狀況下,此 `Model` 是不容許批次賦值任何屬性的哦) // 反之則返回 False $totallyGuarded = $this->totallyGuarded();
Ok,讓咱們回到剛才的 fill 方法繼續往下看設計
接下來是一個 foreach 迴圈,可是在迴圈以前,Laravel 對傳入的賦值屬性執行了 fillableFromArray 這個方法,再點進去看一下,code
protected function fillableFromArray(array $attributes) { if (count($this->getFillable()) > 0 && ! static::$unguarded) { return array_intersect_key($attributes, array_flip($this->getFillable())); } return $attributes; }
此方法會檢測你是否在 fillable 陣列中定義了值,若是定義了值,則會返回 fillable 與 attributes 相交的值,若是沒有,則返回 attributes 自身事件
而後回到 fill ,在呼叫 fillableFromArray 對引數進行處理以後,如今返回的值只剩咱們容許批次賦值的屬性了 (若是你定義了)ip
迴圈第一行,先使用 removeTableFromKey 對引數的 Key 進行處理,刪除鍵中的表名,此方法就不作過多講解,只是一個字串拆分取值的函數rem
$key = $this->removeTableFromKey($key);
接著往下看,Laravel對將要進行填充的每一個屬性都呼叫了 isFillable 方法來確保此屬性是能夠被填充的,讓咱們看一看它的原始碼:
public function isFillable($key) { if (static::$unguarded) { return true; } if (in_array($key, $this->getFillable())) { return true; } if ($this->isGuarded($key)) { return false; } return empty($this->getFillable()) && ! Str::startsWith($key, '_'); }
能夠看到,在此方法中 Laravel 先判斷了此 Model 是否禁用了守衛 (guarded),若是此 Model 並未啟用守衛,那麼直接返回 True
if (static::$unguarded) { return true; }
若是啟用了守衛,那麼會判斷一下此屬性是否存在於 fillable 陣列中,若是存在,則返回 True,
if (in_array($key, $this->getFillable())) { return true; }
若是此屬性不存在於 fillable 陣列中,那麼 Laravel 會再次判斷此屬性是否存在於 guarded 陣列中,若是存在於此陣列中,那麼此屬性就不是一個能夠被批次賦值的屬性,那麼就會直接返回 False
if ($this->isGuarded($key)) { return false; }
若是以上都不符合,那麼 Laravel 在最後會判斷一下自身的 fillable 陣列是為空而且此屬性是以 _ 開頭,而後返回一個布林值
return empty($this->getFillable()) && ! Str::startsWith($key, '_');
而後回到 fill 方法接著看,若是此屬性經過了 isFillable 方法的過濾,那麼將此屬性賦值給自身 (由於時間有限,setAttribute 這個方法就不細講啦~),
$this->setAttribute($key, $value);
若是沒有經過 isFillable 方法的過濾,那麼 Laravel 會判斷一下自身 Model 是否處於不限制任何屬性批次賦值的狀態,若是不是,那麼 Laravel 會直接丟擲一個 Exception
// 判斷此屬性是否經過了檢測 if ($this->isFillable($key)) { // 將此屬性賦值給自身 $this->setAttribute($key, $value); // 若是沒有經過檢測,那麼判斷一下自身 `Model` 是否為所有不可批次賦值狀態,若是是,那麼會丟擲一個 `Exception` } elseif ($totallyGuarded) { throw new MassAssignmentException($key); }
在對全部的屬性進行檢測而且賦值後, Laravel 會將自身返回
return $this;
解析完畢,以上就是 fill 方法的原始碼啦~,最後來一個小結
在你呼叫 fill 方法的時候,Laravel 首先就會去檢測當前 Model 的狀態,
當你設定了 fillable 陣列,沒有設定 guarded 陣列時,那麼此 Model 會處於 僅可批次賦值指定屬性 的狀態
當你沒有設定 fillable 陣列,卻設定了 guarded 陣列時,那麼此 Model 會處於 可批次賦值任何屬性 的狀態
至於你同時設定了 fillable 與 guarded 陣列的狀況就不去討論了,由於這樣作自己就是被 Laravel 所禁止的
而後呼叫 fillableFromArray 去獲取 attributes 與 fillable 陣列的交集,若是你沒有定義 fillable 或者禁用掉了守衛,那麼此方法會直接返回 attributes
而後 Laravel 會對返回的陣列作一個迴圈,在這個迴圈中 Laravel 會對每個屬性呼叫 isFillable 方法檢測這個屬性是否能夠被填充,若是沒有經過此方法的檢測(不存在於fillable 陣列中而且沒有設定 guarded 陣列或存在於 guarded 陣列中),那麼 Laravel會檢測當前 Model 是否處於 僅可批次賦值指定屬性 狀態,若是是,那麼會直接丟擲一個 Exception
而後 Laravel 會返回完成賦值操做後的 $this
【相關推薦:】
以上就是laravel的fill方法怎麼用的詳細內容,更多請關注TW511.COM其它相關文章!