摘要:上一次分析了中的模型事件與觀察者模式這次來解析一下中的用的童鞋應(yīng)該都知道方法是一個給實例賦值屬性的方法讓我們點開方法先看一看它的源碼這里筆者所使用的版本為最新版為了方便閱讀刪除掉了注釋首先可以看到會先去調(diào)用一個自身的方法讓我們點開
上一次分析了 Laravel 中的模型事件與觀察者模式,這次來解析一下 Eloquent 中的 fill
用 Laravel 的童鞋應(yīng)該都知道,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 會先去調(diào)用一個自身的 totallyGuarded 方法,讓我們點開這個方法:
public function totallyGuarded() { return count($this->getFillable()) == 0 && $this->getGuarded() == ["*"]; }
可以看到這個方法的作用就是去獲取自身的 fillable 與 guarded,然后判斷他們是否都為 不可批量賦值 狀態(tài),最后返回一個布爾值
// 返回一個 True or False 的布爾值 // 如果未設(shè)置 fillable 與 guarded,則會返回 True (注意,在這種情況下,此 `Model` 是不允許批量賦值任何屬性的哦) // 反之則返回 False $totallyGuarded = $this->totallyGuarded();
Ok,讓我們回到剛才的 fill 方法繼續(xù)往下看
接下來是一個 foreach 循環(huán),但是在循環(huán)之前,Laravel 對傳入的賦值屬性執(zhí)行了 fillableFromArray 這個方法,再點進去看一下,
protected function fillableFromArray(array $attributes) { if (count($this->getFillable()) > 0 && ! static::$unguarded) { return array_intersect_key($attributes, array_flip($this->getFillable())); } return $attributes; }
此方法會檢測你是否在 fillable 數(shù)組中定義了值,如果定義了值,則會返回 fillable 與 attributes 相交的值,如果沒有,則返回 attributes 自身
然后回到 fill ,在調(diào)用 fillableFromArray 對參數(shù)進行處理之后,現(xiàn)在返回的值只剩我們允許批量賦值的屬性了 (如果你定義了)
循環(huán)第一行,先使用 removeTableFromKey 對參數(shù)的 Key 進行處理,刪除鍵中的表名,此方法就不做過多講解,只是一個字符串拆分取值的函數(shù)
$key = $this->removeTableFromKey($key);
接著往下看,Laravel對將要進行填充的每個屬性都調(diào)用了 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 是否禁用了守衛(wèi) (guarded),如果此 Model 并未啟用守衛(wèi),那么直接返回 True
if (static::$unguarded) { return true; }
如果啟用了守衛(wèi),那么會判斷一下此屬性是否存在于 fillable 數(shù)組中,如果存在,則返回 True,
if (in_array($key, $this->getFillable())) { return true; }
如果此屬性不存在于 fillable 數(shù)組中,那么 Laravel 會再次判斷此屬性是否存在于 guarded 數(shù)組中,如果存在于此數(shù)組中,那么此屬性就不是一個可以被批量賦值的屬性,那么就會直接返回 False
if ($this->isGuarded($key)) { return false; }
如果以上都不符合,那么 Laravel 在最后會判斷一下自身的 fillable 數(shù)組是為空并且此屬性是以 _ 開頭,然后返回一個布爾值
return empty($this->getFillable()) && ! Str::startsWith($key, "_");
然后回到 fill 方法接著看,如果此屬性通過了 isFillable 方法的過濾,那么將此屬性賦值給自身 (因為時間有限,setAttribute 這個方法就不細講啦~),
$this->setAttribute($key, $value);
如果沒有通過 isFillable 方法的過濾,那么 Laravel 會判斷一下自身 Model 是否處于不限制任何屬性批量賦值的狀態(tài),如果不是,那么 Laravel 會直接拋出一個 Exception
// 判斷此屬性是否通過了檢測 if ($this->isFillable($key)) { // 將此屬性賦值給自身 $this->setAttribute($key, $value); // 如果沒有通過檢測,那么判斷一下自身 `Model` 是否為全部不可批量賦值狀態(tài),如果是,那么會拋出一個 `Exception` } elseif ($totallyGuarded) { throw new MassAssignmentException($key); }
在對所有的屬性進行檢測并且賦值后, Laravel 會將自身返回
return $this;
解析完畢,以上就是 fill 方法的源碼啦~,最后來一個小結(jié)
在你調(diào)用 fill 方法的時候,Laravel 首先就會去檢測當(dāng)前 Model 的狀態(tài),
當(dāng)你設(shè)置了 fillable 數(shù)組,沒有設(shè)置 guarded 數(shù)組時,那么此 Model 會處于 僅可批量賦值指定屬性 的狀態(tài)
當(dāng)你沒有設(shè)置 fillable 數(shù)組,卻設(shè)置了 guarded 數(shù)組時,那么此 Model 會處于 可批量賦值任何屬性 的狀態(tài)
至于你同時設(shè)置了 fillable 與 guarded 數(shù)組的情況就不去討論了,因為這樣做本身就是被 Laravel 所禁止的
然后調(diào)用 fillableFromArray 去獲取 attributes 與 fillable 數(shù)組的交集,如果你沒有定義 fillable 或者禁用掉了守衛(wèi),那么此方法會直接返回 attributes
然后 Laravel 會對返回的數(shù)組做一個循環(huán),在這個循環(huán)中 Laravel 會對每一個屬性調(diào)用 isFillable 方法檢測這個屬性是否可以被填充,如果沒有通過此方法的檢測(不存在于fillable 數(shù)組中并且沒有設(shè)置 guarded 數(shù)組或存在于 guarded 數(shù)組中),那么 Laravel會檢測當(dāng)前 Model 是否處于 僅可批量賦值指定屬性 狀態(tài),如果是,那么會直接拋出一個 Exception
然后 Laravel 會返回完成賦值操作后的 $this
以上就是 Eloquent 中 fill 方法的源碼解析啦~,Laravel 的源碼讀下來還是很清晰易懂的~,不得不再次佩服 Laravel 的設(shè)計,不愧為 巨匠級框架
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/26186.html
摘要:根據(jù)單一責(zé)任開發(fā)原則來講,在的開發(fā)過程中每個表都應(yīng)建立一個對外服務(wù)和調(diào)用。類似于這樣解析的數(shù)據(jù)操作分兩種它們除了有各自的特色外,基本的數(shù)據(jù)操作都是通過調(diào)用方法去完成整個。內(nèi)并沒有太多的代碼,大多都是處理數(shù)據(jù)庫鏈接。 showImg(https://segmentfault.com/img/bVbhjvY?w=600&h=296); 前言 提前預(yù)祝猿人們國慶快樂,吃好、喝好、玩好,我會在...
摘要:,看下源碼返回很容易知道返回值是,然后將該值存儲在變量中,這時。看下的源碼去除掉字符后為返回從源碼中可知道返回值為,這時。 說明:本文主要學(xué)習(xí)下Query Builder編譯Fluent Api為SQL的細節(jié)和執(zhí)行SQL的過程。實際上,上一篇聊到了IlluminateDatabaseQueryBuilder這個非常重要的類,這個類含有三個主要的武器:MySqlConnection, M...
摘要:軟刪除當(dāng)模型被軟刪除后,它們并沒有真的從數(shù)據(jù)庫刪除,而是在模型上設(shè)置一個屬性并插入數(shù)據(jù)庫,如果模型有一個非空值,那么該模型已經(jīng)被軟刪除了。 Laravel 中Eloquent ORM 相關(guān)操作 定義 操作 獲取(查詢) 獲取集合,(查詢列表) 返回值是 IlluminateDatabaseEloquentCollection 的一個實例 獲取所有的數(shù)據(jù) use AppUser; $us...
摘要:是一個記錄當(dāng)前應(yīng)用所受威脅情況的項目。怎么做呢用參數(shù)化查詢對數(shù)據(jù)格式化,并使查詢語句與數(shù)據(jù)分離。使用參數(shù)化查詢,可以確保程序遠離注入風(fēng)險。例子如下除此之外,還有一種安全的做法,就是在項目中使用對象關(guān)系映射或者是查詢構(gòu)造器。 showImg(https://segmentfault.com/img/remote/1460000018641613?w=1680&h=859); OWASP?...
摘要:大家有好的文章可以在評論下面分享出來共同進步本文鏈接數(shù)組使用之道程序員進階學(xué)習(xí)書籍參考指南教你在不使用框架的情況下也能寫出現(xiàn)代化代碼巧用數(shù)組函數(shù)框架中間件實現(xiàn)沒錯,這就是面向?qū)ο缶幊淘O(shè)計模式需要遵循的個基本原則令人困惑的在中使用協(xié)程實現(xiàn)多任 大家有好的文章,可以在評論下面分享出來, 共同進步! 本文github鏈接 php PHP 數(shù)組使用之道 PHP程序員進階學(xué)習(xí)書籍參考指南 教你...
閱讀 860·2019-08-30 15:54
閱讀 3327·2019-08-29 15:33
閱讀 2711·2019-08-29 13:48
閱讀 1237·2019-08-26 18:26
閱讀 3343·2019-08-26 13:55
閱讀 1499·2019-08-26 10:45
閱讀 1177·2019-08-26 10:19
閱讀 318·2019-08-26 10:16