天天看點

PHP autoload 自動加載機制

背景

在php5之前,如果要使用某個類,需要用include/require将其包含進來即可。随着項目規模不斷變大,這種方式會造成一些問題:需要大量的reuqure/include語句;加載不必要的類;維護起來特别困難;一個引用錯誤整體會報錯。

php5為了解決這個問題,提供了“類的自動加載"機制。

autoload機制

如果加載一個類,該類沒有被加載,則自動運作__autoload函數

function __autoload($classname) {

require_once ($classname . "class.php");

}

該函數實作步驟:

第一步:将類名轉化成檔案名

第二補:确定實際的磁盤位址

第三部:require/include

是以,我們隻需要在__autoload()函數中,将類名和檔案名按照一定規則對應起來,就可以實作類的自動加載。

問題出現了,在實際開發中,對應規則并不是一成不變的,如果類和實際磁盤檔案的映射規則有很多,是不是__autoload()函數就會顯得十分臃腫?

繼續探究php的自動加載機制,發現并不是簡單的調用__autoload()函數這麼簡單。其實是這個樣子:

檢查執行器全局變量函數指針autoload_func如果為null

定義了__autoload()函數,執行,并傳回結果。

未定義__autoload()函數,報告錯誤并退出

檢查執行器全局變量函數指針autoload_func不為null,執行autoload_func函數。autoload_func函數是幹啥的呢,繼續往下看。

SPL autoload機制

SPL是Standard PHP Library(标準PHP庫)的縮寫,spl可以将函數指針autoload_func指向自己實作的自動加載函數。spl有兩個函數:sql_autoload和sql_autoload_call。

spl_autoload函數,有兩個參數,一個是類名,一個是檔案拓展名,可以多個。實際上和__aotoload差不多。

spl_autoload_call内部有一個全局變量autoload_functions,本質上就是一個連結清單,一個元素指向一個指針,指向一個自動加載類的函數,在執行的時候按照順序一個一個自動加載方法去加載,找到類就終止。

php自動加載到底怎麼走呢?有一個函數起到了至關重要的作用,spl_autoload_register。

spl_autoload_register()沒有參數就是讓autoload_func執行spl_autoload。有參數,比如定義了一個自動加載類方法test,spl_autoload_register(test())就是讓autoload_func執行spl_autoload_call