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