PHP的類自動(dòng)加載機(jī)制
-
手動(dòng)加載方式
像C和C++等語(yǔ)言,在PHP中需要使用另一個(gè)文件中的相關(guān)的類、方法時(shí),可以使用include、include_once、require或者require_once將所用的文件包含進(jìn)工程里面。
- include將套用一個(gè)文件,如果文件不存在,則給出一個(gè)提示,跳過繼續(xù)執(zhí)行;
- include_once也是套用一個(gè)文件,但是只會(huì)套用一次,如果文件不存在,則繼續(xù)執(zhí)行
- require表示套用一個(gè)文件,如果文件不存在,則中斷程序的執(zhí)行;
- require_once也是套用一個(gè)文件,且只會(huì)套用一次,如果文件不存在,則中斷程序的執(zhí)行;
以上四種方式是需要什么文件的時(shí)候,手動(dòng)在程序當(dāng)中包含進(jìn)文件。這在項(xiàng)目的規(guī)模比較小的時(shí)候,是可以的;但是隨著項(xiàng)目規(guī)模的擴(kuò)大,要通過手動(dòng)的方式加載每個(gè)文件所需要的類簡(jiǎn)直是一場(chǎng)噩夢(mèng)。
-
自動(dòng)加載方式
為了將雙手從類的加載方式中解放出來,在PHP5及以后的版本中提供了一個(gè)自動(dòng)加載的機(jī)制---
autoload。Autoload可以使類在確實(shí)被需要的情況下才會(huì)被加載進(jìn)來,也就是所謂的lazy loading,而不是一開始就include或者require所有的類文件。其中PHP提供的自動(dòng)加載機(jī)制又分為兩種__autoload()以及spl_autoload_register()。- __autoload
在PHP5中運(yùn)行程序的過程中,如果發(fā)現(xiàn)某一個(gè)類并沒有被包含進(jìn)來,那么就會(huì)運(yùn)行__autoload自動(dòng)加載機(jī)制,將所需要的類加載進(jìn)來。其寫法如下:
< ? php public function __autoload($classname) { $fileName = $classname."php"; if (file_exist($fileName)) { require_once("$fileName"); } else { echo $fileName." doesn't exist!" } }這個(gè)程序?qū)懛?,我們可以得到如下的結(jié)論:保證自動(dòng)加載機(jī)制的的原則就是要使得類名和文件名具有一種對(duì)應(yīng)關(guān)系,類名+后綴構(gòu)成了這個(gè)類所在的文件的名字。如果這個(gè)文件確實(shí)存在,那么就根據(jù)$fileName將該類加載進(jìn)來。如果文件不存在,則提示用戶,文件不存在??偟膩碚f自動(dòng)加載機(jī)制包括三個(gè)步驟:
根據(jù)類名確定文件名,也就是確定一種類名和文件名之間的統(tǒng)一對(duì)應(yīng)規(guī)則;根據(jù)文件名在磁盤上找到相應(yīng)的對(duì)應(yīng)文件(例子中是最簡(jiǎn)單的情況,就是類與調(diào)用他們的PHP文件都在同一個(gè)目錄下);如果不在同一個(gè)目錄下,那么可以使用set_include_path()指定要加載的路徑;-
將磁盤文件加載到文件系統(tǒng)中,這一步只是用一般的include和require包含相應(yīng)的類文件;
__autoload()實(shí)現(xiàn)類的自動(dòng)加載的原則就是:類名和文件名之間具有一種統(tǒng)一的對(duì)應(yīng)關(guān)系,這是在一個(gè)系統(tǒng)中實(shí)現(xiàn)__autoload的關(guān)鍵所在。但是一個(gè)系統(tǒng)可能是有不同的人員所開發(fā),如果在開發(fā)之前沒有約定統(tǒng)一的標(biāo)準(zhǔn),則可能存在不同的對(duì)應(yīng)規(guī)則,導(dǎo)致需要在__autoload()中實(shí)現(xiàn)多種加載規(guī)則,那么可能導(dǎo)致__autoload()函數(shù)非常的臃腫。為了解決這個(gè)這個(gè)問題,PHP還提供了一個(gè)自動(dòng)加載機(jī)制---spl_autoload_register().
- __autoload
spl_autoload_register()
<? php
function autoload1($classname) {
$fileName = $classname.".php";
if (file_exist($fileName)) {
require_once("$fileName");
} else {
echo $fileName." doesn't exist!"
}
}
function autoload2($classname) {
$fileName = $classname.".class.php";
if (file_exist($fileName)) {
require_once("$fileName");
} else {
echo $fileName." doesn't exist!"
}
spl_autoload_register("autoload1");
spl_autoload_register("autoload2");
}