ThinkPHP6 核心分析之Http 類跟Request類的例項化
阿新 • • 發佈:2020-07-24
以下原始碼分析,我們可以從 App,Http 類的例項化過程,瞭解類是如何實現自動例項化的,依賴注入是怎麼實現的。
$bind 的值是一組類的標識到類的對映。從這個實現也可以看出,我們不僅可以在 provider.php 檔案中新增標識到類的對映,而且可以覆蓋其原有的對映,也就是將某些核心類替換成自己定義的類。
static::setInstance($this) 實現的作用,如圖:
think\App 類的 $instance 成員變數指向 think\App 類的一個例項,也就是類自己儲存自己的一個例項。
instance() 方法的實現:
其中的getAlias方法:
執行結果大概是這樣的:
然而,實際上,主要是make()方法:
然而,make()方法主要靠invokeClass()來實現類的例項化。該方法具體分析:
以上程式碼可看出,在一個類中,新增__make()方法,在類例項化時,會最先被呼叫。以上最值得一提的是bindParams()方法:
而這之中,又最值得一提的是getObjectParam()方法:
getObjectParam() 方法再一次光榮地呼叫 make() 方法,例項化一個類,而這個類,正是從 Http 的建構函式提取的引數,而這個引數又恰恰是一個類的例項 ——App 類的例項。到這裡,程式不僅通過 PHP 的反射類例項化了 Http 類,而且例項化了 Http 類的依賴 App 類。假如 App 類又依賴 C 類,C 類又依賴 D類…… 不管多少層,整個依賴鏈條依賴的類都可以實現例項化。
總的來說,整個過程大概是這樣的:需要例項化 Http 類 ==> 提取建構函式發現其依賴 App 類 ==> 開始例項化 App 類(如果發現還有依賴,則一直提取下去,直到天荒地老)==> 將例項化好的依賴(App 類的例項)傳入 Http 類來例項化 Http 類。
這個過程,起個裝逼的名字就叫做「依賴注入」,起個摸不著頭腦的名字,就叫做「控制反轉」。
這個過程,如果退回遠古時代,要例項化 Http 類,大概是這樣實現的(假如有很多層依賴):
這得有多累人。而現代 PHP,交給「容器」就好了。
另外,需要提的一點是 make 方法的 $vars 引數,它的形式可以是普通陣列、關聯陣列,而且陣列中元素的值可以是一個類的例項。$vars 引數的值最終將傳遞給要例項化的類的建構函式或者__make 方法中對應的引數。