萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> php編程 >> PHP的類自動加載機制的筆記

PHP的類自動加載機制的筆記

在php中自動加載我們會使用到方法__autoload spl_autoload_register來實現,像我們有幾百個類時我們希望是希望使用__autoload來創建,然後直接創建類名就可以了,下面簡單的總結了一下自動加載類的用法,希望對各位有幫助。

在PHP5之前,各個PHP框架如果要實現類的自動加載,一般都是按照某種約定自己實現一個遍歷目錄,自動加載所有符合約定規則的文件的類或函數。 當然,PHP5之前對面向對象的支持並不是太好,類的使用也沒有現在頻繁。 在PHP5後,當加載PHP類時,如果類所在文件沒有被包含進來,或者類名出錯,Zend引擎會自動調用__autoload 函數。此函數需要用戶自己實現__autoload函數。 在PHP5.1.2版本後,可以使用spl_autoload_register函數自定義自動加載處理函數。當沒有調用此函數,默認情況下會使用SPL自定義的spl_autoload函數。 看下面兩個例子:

1、 __autoload示例:

 代碼如下 復制代碼

function __autoload($class_name) {
   echo '__autload class:', $class_name, '<br />';
}
new Demo();

以上的代碼在最後會輸出:__autload class:Demo。
並在此之後報錯顯示: Fatal error: Class 'Demo' not found

2、spl_autoload_register示例:

 代碼如下 復制代碼

function classLoader($class_name) {
    echo 'SPL load class:', $class_name, '<br />';
}
spl_autoload_register('classLoader');
new Demo();

以上的代碼在最後會輸出:SPL load class:Demo。
並在此之後報錯顯示: Fatal error: Class 'Demo' not found

以上的兩個示例表明:當類不存在時(即需要的類不在類符號表),Zend引擎會將再調用一次用戶定義的函數,如__autoload或spl_autoload_register注冊的函數。 如果這兩個方法同時存在,那麼程序會調用哪一個呢?還是說兩個都調用?看下面一個示例,你覺得會輸出什麼呢?

 代碼如下 復制代碼

function __autoload($class_name) {
    echo '__autload class:', $class_name, '<br />';
}
function classLoader($class_name) {
    echo 'SPL load class:', $class_name, '<br />';
}
spl_autoload_register('classLoader');
new Demo();

 __set、__tostring等類的魔法方法的常量定義在源碼級別是一起的, 可是它並不是專屬於某個類的魔法方法。它是所有的類共用的自動加載魔術方法。 它將作為一個全局函數存在。那麼Zend引擎是如何在類沒有找到時調用這個方法的呢?

不管是使用new關鍵字創建類的實例,還是使用implement實現接口,或者繼承某個類, 所有的這些操作都有可能調用__autoload函數。這幾個操作在源碼層都有一個共同點,它們在執行的時候都需要獲取類的信息(接口在本質上也是一個類)。 它們在最終都會調用 zend_fetch_class (Zend/zend_execute_API.c)函數,這個函數本身沒有多少內容,關鍵是它調用了zend_lookup_class_ex(Zend/zend_execute_API.c)函數, 這個函數就是類的自動加載的真相所在。

在zend_lookup_class_ex函數中,我們看到程序會首先查詢類符號表,如果存在類直接返回。如果不存在,就會執行我們所說的自動加載了。這裡針對__autoload函數和spl相關的函數都做了處理,並且以第一參數和第二參數傳遞給Zend引擎的函數調用函數zend_call_function。

在zend_call_function函數中,它會判斷第二參數是否存在函數,如果存在函數則只會調用第二個參數傳遞的函數(這裡指SPL注冊的函數)。如果第二個函數沒有值,則執行第一個參數傳遞過來的函數(這裡指用戶定義的__autoload函數)。到這裡,我想前面提到的兩個方法同時存在的情況應該就有答案了,這也算是一篇基於的php教程了。

copyright © 萬盛學電腦網 all rights reserved