PHP的自動加載類的機制以及實現

最近偶然看到了php的自動加載類,小小研究一番,在此寫下我的心得。

我們在進行小規模的開發時,常常會用require或者include引用系統的公共文件(.php,.inc,.class.php),或者你嘗試使用一個未知類時,會產生致命錯誤,這時你也可以用上述方法。但是在大型的開發中,這麼做會產生大量的require或者include方法調用,這樣做會降低效率,代碼的可維護性也會大大降低,況且require_once的代價很大。

所以php的自動加載函數__autoload()和spl_autoload_register()就派上了用場。

首先是__autoload()函數:

假設當前目錄下每個文件對應一個類. 當腳本嘗試來產生一個類User的實例,PHP會執行__autoload. 假設class_User.php中定義有User類.. 不管調用時是大寫還是小寫,PHP將返回名稱的小寫。

但是問題又來了,從__autoload中拋出的異常不能被catch語句塊捕獲並導致致命錯誤,而且當一個大型項目開發中引入多個類庫時,可能因爲各個類庫之間不同的__autoload機制而導致一些難以理解的錯誤,因此我們多了一種選擇,那就是spl_autoload_register()函數(php5引入SPL標準庫以後)。

此函數的功能就是把函數註冊至SPL的__autoload函數棧中,並移除系統默認的__autoload()函數。

語法:bool  spl_autoload_register ( [callback $autoload_function] )    接受兩個參數:一個是添加到自動加載棧的函數,另外一個是加載器不能找到這個類時是否拋出異常的標誌。第一個參數是可選的,並且默認指向spl_autoload()函數,這個函數會自動在路徑中查找具有小寫類名和.php擴展或者.ini擴展名,或者任何註冊到spl_autoload_extensions()函數中的其它擴展名的文件。

也可以使用類的方法來實現自定義的加載函數

 

一旦調用spl_autoload_register()函數,當調用未定義類時,系統會按順序調用註冊到spl_autoload_register()函數的所有函數,而不是自動調用__autoload()函數。如果要避免這種情況,需採用一種更加安全的spl_autoload_register()函數的初始化調用方法:

 

spl_autoload_functions()函數會返回已註冊函數的一個數組,如果SPL自動加載棧還沒有被初始化,它會返回布爾值false。然後,檢查是否有一個名爲__autoload()的函數存在,如果存在,可以將它註冊爲自動加載棧中的第一個函數,從而保留它的功能。之後,可以繼續註冊自動加載函數。

還可以調用spl_autoload_register()函數以註冊一個回調函數,而不是爲函數提供一個字符串名稱。如提供一個如array('class','method')這樣的數組,使得可以使用某個對象的方法。

下一步,通過調用spl_autoload_call('className')函數,可以手動調用加載器,而不用嘗試去使用那個類。這個函數可以和函數class_exists('className',false)組合在一起使用以嘗試去加載一個類,並且在所有的自動加載器都不能找到那個類的情況下失敗。

SPL自動加載功能是由spl_autoload() ,spl_autoload_register(), spl_autoload_functions() ,spl_autoload_extensions()和spl_autoload_call()函數提供的。

 

 

一般情況下,推薦使用spl_autoload_register()來處理;

還可以通過spl_autoload_functions()查看你當前註冊了多少autoload函數。

另外在linux和unix環境下,還有很多技巧,有待學習。

 


 

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