深入學習Composer原理(二)

本系列的第二篇文章,這次我們聊聊:spl_autoload_register()函數

PHP的SPL庫作爲擴展庫,已經於5.3.0版本後默認保持開啓,成爲PHP的一組強大的核心擴展庫。大家有時間可以多研究研究SPL裏面的方法功能。而且,SPL中包含很多類庫喲,在設計模式的系列文章中,我們也會再次見到他們的身影!

這回我們建立一個文件,叫做spl_autoload_register.php,然後將下面的代碼複製進去吧:

 
<?php
 
spl_autoload_register(function( $className ){
    require $className . '.php';
});
 
$m = new TestClass();
$m->show();
 
 
 
是不是和__autoload()很像,當然作用也很像。我們直接運行這個文件試試,會發現TestClass.php也正常的加載了進來。那麼爲啥不直接用__autoload()函數,而使用sql_autoload_register()這麼詭異的函數,而且還有個神奇的閉包參數!!!

我們先看看它的定義和格式

PHP官方文檔中的定義

註冊給定的函數作爲 __autoload 的實現

沒錯,那個匿名函數就是一個__autoload()函數,我們可以理解爲給當前這個PHP文件中註冊一個__autoload()函數,而使用匿名函數的原因呢?當然就是爲了閉包特性,最主要的就是能夠帶來延遲加載(懶加載 )的實現!

另外,spl_autoload_register()函數不止是僅僅去註冊一個__autoload(),它實現並維護了一個__autoload()隊列。原來在一個文件中只能有一個__autoload()方法,但現在,你擁有的是一個隊列。

函數格式

spl_autoload_register ([ callable throw = true [, bool $prepend = false ]]] ) : bool

有點長,我們一步步看:

  • callable $autoload_function:閉包函數,不多解釋了,上面已經說了,不瞭解閉包函數的作用可以百度百度
  • bool autoload_function無法成功註冊時,是否拋出異常
  • bool $prepend:如果是true,將會添加一個__autoload()函數到隊列的頂部
  • 這個函數有返回值,成功或失敗

改造代碼

嗯,到這裏好像有點複雜了,我們需要改造改造代碼這樣才能讓大家看得更清晰,先準備另一個需要加載 的類文件,就叫CaseClass.php好了

<?php
 
class CaseClass
{
    public function show()
    {
        echo "Good!\n";
    }
}
 
然後修改spl_autoload_register.php文件
<?php
 
// 使用匿名函數方式
spl_autoload_register(function( $className ){
    echo "first==>\n";
    require_once 'TestClass.php';
});
 
// 需要註冊的外部__autoload()實現
spl_autoload_register('CaseAutoLoad');
 
function CaseAutoLoad( $className ){
    echo "second==>\n";
    require_once 'CaseClass.php';
}
 
$m = new TestClass();
$m->show();
 
echo "--------\n";
 
$s = new CaseClass();
$s->show();
 

什麼都別說了,直接運行吧,如果有報錯請檢查下哪裏寫錯了,反正我這裏沒錯~~

正常情況下應該輸出這樣的內容

  1. "first==>"是我們原來的spl_autoload_register()函數輸出的內容,這裏我們沒有使用$className來動態加載,而是隻加載TestClass.php這一個文件
  2. 接下來我們便輸出了TestClass裏面的show()方法的內容。需要注意的是:這裏可還沒有加載CaseClass.php這個文件哦,也就是現在我們已經實現了懶加載了哦
  3. 接下來,我們想要實例化CaseClass對象,於是spl_autoload_register()維護的隊列發揮作用了。先走第一條,利用require_once()對於之前已經加載過的TestClass.php不會再次加載了。但是這一個文件中並沒有找到我們需要的CaseClass對象,於是我們進入了隊列第二條,來到了CaseAutoLoad()方法中,CaseClass.php終於在這個方法中被require_once()進來了

到這裏,你已經知道了這個函數最大的作用就是維護的這個隊列並且可以延遲加載我們需要的文件。是不是感覺有點要走上人生巔峯了?不不不,你心裏或許還在疑惑,這玩意跟Composer有啥關係?

請在您需要測試的目錄初始化一個Composer

  • 進入vendor/composer/autoload_real.php中
  • 在getLoader()方法中馬上就能發現spl_autoload_register()方法
  • 然後在最底下有個loader就是ClassLoader類
  • 進入ClassLoader.php文件中,找到register()方法- 沒錯,裏面還是一個spl_autoload_register()方法,這樣來看,這貨就是Composer的靈魂啊!!

OK,走到這裏,其實在面試的時候就可以跟面試官司吹牛了,Composer的原理?spl_autoload_register()方法嘛。說不定確實有不少人就被你唬住了,但是,對於Composer來說,我們還有一個非常重要的方面不能忽略,可以將它看作是Composer的血肉,讓自動加載能夠有形,成爲一個有靈魂有軀體的完整的人,這就是PSR規範中的PSR0和PSR4規範,下篇我們就聊聊這倆貨!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章