深入學習Composer原理(二)

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

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

這回我們建立一個文件,叫做spl_autoload_register.php,然后將下面的代碼復(fù)制進去吧:


<?php

spl_autoload_register(function( $className ){
    require $className . '.php';
});

$m = new TestClass();
$m->show();

是不是和__autoload()很像,當然作用也很像。我們直接運行這個文件試試,會發(fā)現(xiàn)TestClass.php也正常的加載了進來。那么為啥不直接用__autoload()函數(shù),而使用sql_autoload_register()這么詭異的函數(shù),而且還有個神奇的閉包參數(shù)?。?!

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

PHP官方文檔中的定義

注冊給定的函數(shù)作為 __autoload 的實現(xiàn)

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

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

函數(shù)格式

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

有點長,我們一步步看:

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

改造代碼

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

<?php

class CaseClass
{
    public function show()
    {
        echo "Good!\n";
    }
}

然后修改spl_autoload_register.php文件

<?php

// 使用匿名函數(shù)方式
spl_autoload_register(function( $className ){
    echo "first==>\n";
    require_once 'TestClass.php';
});

// 需要注冊的外部__autoload()實現(xiàn)
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();

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

正常情況下應(yīng)該輸出這樣的內(nèi)容

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

到這里,你已經(jīng)知道了這個函數(shù)最大的作用就是維護的這個隊列并且可以延遲加載我們需要的文件。是不是感覺有點要走上人生巔峰了?不不不,你心里或許還在疑惑,這玩意跟Composer有啥關(guān)系?

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

  • 進入vendor/composer/autoload_real.php中
  • 在getLoader()方法中馬上就能發(fā)現(xiàn)spl_autoload_register()方法
  • 然后在最底下有個loader->register(true);方法-- 簡單的閱讀代碼我們發(fā)現(xiàn)其實這個loader就是ClassLoader類
  • 進入ClassLoader.php文件中,找到register()方法- 沒錯,里面還是一個spl_autoload_register()方法,這樣來看,這貨就是Composer的靈魂?。?!

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

完整源碼:GitHub

===============

關(guān)注公眾號:【硬核項目經(jīng)理】獲取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料

知乎、公眾號、抖音、頭條搜索【硬核項目經(jīng)理】

B站ID:482780532

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容