這篇文章為大家帶來了thinkphp中loader自動載入的相關知識,主要包含了Composer載入的相關知識,希望對大家有幫助!
一、自動載入loader原始碼分析
1-1 學習目標
類別的自動載入
類別自動載入的兩個方式
spl_autoload_register必須會使用
來實現自訂檔案的類別的自動載入
1-2 Composer載入
在這裡插入圖片描述
在base.php中首先載入了loader類,接著調用了register這個方法。
來到thinkphp\library\think\Loader.php有一個register的方法,在這個方法裡邊,我們先學習第一個知識點spl_autoload_register()聊聊spl_autoload_register前世今生和簡單使用,直接點擊即可查看。
緊接著就是專案的根路徑和composer的路徑。
在這裡插入圖片描述
從這裡開始就是在載入composer文件,過程也是很簡單
判斷composer是否為目錄
判斷路徑下面的autoload_static.php是否為檔案
引入autoload_static.php檔案
返回所有已經聲明的所有類 數組返回
獲取最後一個類ComposerStaticInit30742487e00917c888d89ba216f165b9
判斷ComposerStaticInit30742487e00917c888d89ba216f165b9中是否存在陣列中的資料
接著可以去vendor\composer\autoload_static.php檔案中可以看到這兩個屬性
#這裡有一段程式碼估計有一部分同學會在這裡繞一下self::${$attr} = $composerClass::${$attr};,這裡的$attr就是'prefixLengthsPsr4' , 'prefixDirsPsr4', 'fallbackDirsPsr4', 'prefixesPsr0', 'fallbackDirsPsr0', 'classMap', 'files'這些數據,外層在加一個$符號。
因此在ComposerStaticInit30742487e00917c888d89ba216f165b9這個類別中直接取得對應的屬性值,也就是上圖的兩個屬性值。
1-3 註冊命名空間
#檔案或thinkphp\library\think\Loader.php的register方法
在這裡註冊了兩個指令空間,分別為think和traits。接著會進入addNamespace這個方法
在addNamespace方法中,加入了Psr4空間
接著來到addPsr4這個方法,會把這倆個命名空間都註冊到
ComposerStaticInit1e269472f484e157e90227b420ffca7a類的$prefixLengthsPsr4和$prefixDirsPsr4這倆個屬性中
為了驗證上面做一個斷點調試,看到這些資料就應該清晰了,至於traits也是一樣的註冊方式。
截止到這裡命名空間就註冊完成了,接下來研究一下psr4命名空間是個什麼東東。
1-4 Psr4是什麼玩意
psr是簡單的理解就是檔案路徑、自動載入對應類別的相關規範、目前TP5.1使用的是psr4規範
此處的類別是指class、介面、超類別結構
一個完整的類別需要一下結構\( \)*\
以下規格源自於PHP文件
完整的類別名稱必須要有一個頂層命名空間,被稱為"vendor namespace";
完整的類別名稱可以有一個或多個子命名空間;
完整的類別名稱必須有一個最終的類別名稱;
完整的類別名稱中任一部分中的下滑線都是沒有特殊意義的;
完整的類別名稱可以由任意大小寫字母組成;
所有類別名稱都必須是大小寫敏感的。
以下是官方給的一個例子,這個psr規範能理解就盡量去理解它
1- 5 載入類別庫映射檔
到這裡,一定會有一個疑問,這裡怎麼沒有classmap.php這個檔。
不急不慌,先執行php think optimize:autoload把檔案弄出來
最後會走到addClassMap這個方法,在這個方法中,只是把classmap.php這個檔案的資料賦值給$classMap 而已,沒有什麼其它的用法
1-6自動載入extend目錄
extend這個目錄用過TP框架的都多少用過的,在這個目錄裡邊可以存放一下自訂的類別庫檔案。
根據下圖可以看到就是使用addAutoLoadDir這個方法進行載入的
#在方法中也只是把extend的路徑賦值給了$fallbackDirsPsr4這個屬性。
截止到這裡Loader::register();這部分就結束了,接著我們深入的看一下內部實作和實作案例。
在上述閱讀原始碼中有四個屬性,簡單的整理一下
#二、簡說類別的載入過程
#在這裡插入圖片描述
在剛開始解析這裡的原始碼時就有一個函數spl_autoload_register
當需要使用的類別沒有被引入時,這個函數會在PHP報錯前被觸發,未定義的類別名稱會被當作參數傳入這裡會直接去執行think \\Loader::autoload這個方法
經過斷點第一個未載入的類別就是think\Error
為什麼是think\Error呢!可以在回到thinkphp/base.php看一下,當自動載入完執行完成後第一個執行的類別就是Error
可以簡單的做個測試,將這Error改為Kaka,進行列印一下,這時的類別就改變為Kaka。到這裡大家對這個類別的自動載入機制就有一定的了解了。
當使用的類別沒有被引入時會把這個類別當作參數傳到thinkphp/library/think/Loader.php的autoload方法中。
到這裡在進行看一下autoload這個方法
#先從findFile這個方法走,把未因為的類別傳入這個方法中,在findFile這個方法中會直接從classMap這個屬性直接把think\Error這個類別對映的檔案直接回傳
將think\ Error這個類別的完整路徑回傳給autoload的file變數後,把win環境的大小寫給判斷了一次。
然後直接使用include引入檔案即可,直到返回。
直到這裡就是一次完整的類別的自動載入解析。
雖然到這裡結束了,但是還是得在提一點就是$classMap這個屬性,這個屬性是基於檔案classmap.php來到,這個檔案的產生也是需要執行指令php think optimize:autoload產生的。
當沒有產生這個檔案時程式是如何執行的呢!
之前的所有流程都是一樣的,只有在findFile這裡不一樣,接下來進行簡單的梳理一下。
這時程式碼絕對不會走classMap
先取得think\Error檔案
接著經過Composer自動載入中的兩個屬性進行取得命名空間,在把think\Error.php檔案進行拼接
最終回傳的結果也是D:\phpstudy_pro\ WWW\ThinkPHPSourceCodeAnalysis\thinkphp\library\think\Error.php這個檔案。
這裡的程式碼需要好好的閱讀一下。
類別的自動載入到這裡就是完全結束了。
三、自訂檔案如何實現類別的自動載入
#先建立一個資料夾kaka
這時在控制器index中引入檔案Kaka.php
#直接進行訪問,這時這個類別肯定會報錯,那麼我們該怎麼操作一下,就可以直接訪問呢!
在這裡插入圖片描述
這時候就提現到原始碼的重要性了,還記得在自動載入的register函數中,載入過extend目錄
在這裡插入圖片描述
這時在加一個kaka這個目錄,直接進行訪問一下
沒毛病,直接就出來了。一切OK在這裡在聊一下關於extent的載入方式
在之前聊註冊自動載入類別庫目錄只是說明了一下只是把路徑存到了$fallbackDirsPsr4屬性,沒有細細說,接下來就是說明這些了。
閱讀原始碼只能是實作那然後查看那個
在這裡插入圖片描述
只要是定義的類別都會進去到autoload進行自動載入
同樣也會進入findFile這個方法
#在findFile這個方法中可以看到這段程式碼,這個屬性是不是很熟悉,就是自動載入extend目錄時加入到$fallbackDirsPsr4屬性的。
當在findFile中列印參數class時看一下資料
很清楚地可以看到test\Kaka這個類別
此時在列印這個$fallbackDirsPsr4屬性裡邊回傳的file
##然後就是使用__include_file來直接includeD:\phpstudy_pro\WWW\ThinkPHPSourceCodeAnalysis\kaka\test\Kaka.php我們定義的檔案。 以上的這個自訂檔案如何實作類別的自動加載,也就是extend的載入方式(推薦學習:thinkphp5)
以上是怎麼理解ThinkPHP的Loader自動載入的詳細內容。更多資訊請關注PHP中文網其他相關文章!