在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影片教學】
以上是laravel的fill方法怎麼用的詳細內容。更多資訊請關注PHP中文網其他相關文章!