什么是__autoload?
php是腳本語(yǔ)言,不同于c++只需要編譯一次,php每次執(zhí)行過(guò)程中都需要編譯,所以提高php編譯效率,可以提高php腳本執(zhí)行速度。
每次,當(dāng)你使用一個(gè)新的類(lèi)時(shí),你需要包含這個(gè)類(lèi)文件,然后在new出這個(gè)類(lèi)。當(dāng)一個(gè)腳本中依賴(lài)了很多其他腳本中定義的類(lèi)時(shí),往往腳本的樣子如下:
/**
* 文件non_autoload.php
*/
require_once(‘your/proj/inc/A.php’);
require_once(‘your/proj/inc/B.php’);
require_once(‘your/proj/inc/C.php’);
if(條件A) {
$a=newA();
$b=newB();
$c=newC();
// … 業(yè)務(wù)邏輯
}elseif(條件B) {
$a= newA();
$b=newB();
// … 業(yè)務(wù)邏輯
}
這樣就會(huì)有一個(gè)問(wèn)題:如果腳本執(zhí)行“條件B”這個(gè)分支時(shí),C.php這個(gè)文件其實(shí)沒(méi)有必要包含。因?yàn)?,任何一個(gè)被包含的文件,無(wú)論是否使用,均會(huì)被php引擎編譯。如果不使用,卻被編譯,這樣可以被視作一種資源浪費(fèi)。更進(jìn)一步,如果C.php包含了D.php,D.php包含了E.php。并且大部分情況都執(zhí)行“條件B”分支,那么就會(huì)浪費(fèi)一部分資源去編譯C.php,D.php,E.php三個(gè)“無(wú)用”的文件。
這時(shí)候,可以通過(guò)PHP的__autoload方法去除這種浪費(fèi),__autoload方法提供一種“l(fā)azy load”的機(jī)制,當(dāng)?shù)谝淮涡枰褂孟嚓P(guān)類(lèi)時(shí)調(diào)用,這樣就不會(huì)加載不必要的類(lèi)。還是通過(guò)上面的例子,修改如下:
/**
* 文件autoload_demo.php
*/
function__autoload($className) {
$filePath= “your/proj/inc/{$className}.php”;
if(is_readable($filePath)) {
require($filePath);
}
}
if(條件A) {
$a=newA();
$b=newB();
$c=newC();
// … 業(yè)務(wù)邏輯
}elseif(條件B) {
$a= newA();
$b=newB();
// … 業(yè)務(wù)邏輯
}
可以看到,文件開(kāi)頭去掉了連串的require方法,使用了php的魔術(shù)方法__autoload替代。該函數(shù)的工作原理如下:
當(dāng)php引擎第一次使用類(lèi)A,但是找不到時(shí),會(huì)自動(dòng)調(diào)用__autoload方法,并將類(lèi)名“A”作為參數(shù)傳入。所以,我們需要的做的就是根據(jù)類(lèi)名,找到對(duì)應(yīng)的文件,并包含進(jìn)來(lái),如果我們的方法也找不到,那么php引擎就會(huì)報(bào)錯(cuò)。注意,這里可以只用require,因?yàn)橐坏┌M(jìn)來(lái)后,php引擎再遇到類(lèi)A時(shí),將不會(huì)調(diào)用__autoload,而是直接使用內(nèi)存中的類(lèi)A,不會(huì)導(dǎo)致多次包含。
所以,使用__autoload的關(guān)鍵在于,如何根據(jù)類(lèi)名,找到對(duì)應(yīng)類(lèi)定義的文件。