5.16日音訊,程序開(kāi)發(fā)中php實(shí)現(xiàn)自動(dòng)加載。在使用PHP的OO模式開(kāi)發(fā)系統(tǒng)時(shí),通常大家習(xí)慣上將每個(gè)類的實(shí)現(xiàn)都存放在一個(gè)單獨(dú)的文件里,這樣會(huì)很容易實(shí)現(xiàn)對(duì)類進(jìn)行復(fù)用,同時(shí)將來(lái)維護(hù)時(shí)也很便利。這也是OO設(shè)計(jì)的基本思想之一。在PHP5之前,如果需要使用一個(gè)類,只需要直接使用include/require將其包含進(jìn)來(lái)即可,使用require,include,require_once,include_once手工進(jìn)行加載。
使用__autoload來(lái)進(jìn)行自動(dòng)加載
使用spl的autoload來(lái)實(shí)現(xiàn)自動(dòng)加載
手工加載的實(shí)現(xiàn):
當(dāng)需要加載的文件很少的時(shí)候我們可以使用第一個(gè)來(lái)完成。這樣做很簡(jiǎn)單也沒(méi)問(wèn)題。
[php]
require_once'a.php';
require_once'b.php';
require_once'c.php';
require_once'a.php';
require_once'b.php';
require_once'c.php';
但是當(dāng)需要加載文件很多的時(shí)候這樣做還行嗎?需要寫(xiě)十個(gè),二十個(gè)require_once或者更多的時(shí)候我們?cè)撛趺崔k?
這個(gè)時(shí)候我們可以使用__autoload方法來(lái)簡(jiǎn)化我們的代碼。
__autoload加載的實(shí)現(xiàn):
我們?cè)趖est目錄下創(chuàng)建一個(gè)in.php文件,內(nèi)容如下。
[php]
echo'我是test下面的in.php<br/>';
echo'我是test下面的in.php<br/>';然后在test目錄下創(chuàng)建一個(gè)loader.php,內(nèi)容如下。
[php]
//需要重載__autoload方法,自定義包含類文件的路徑
function__autoload($classname)
{
$class_file=strtolower($classname).".php";
if(file_exists($class_file)){
require_once($class_file);
}
}
@$test=newin();//執(zhí)行到這里會(huì)輸出<SPANstyle="FONT-FAMILY:Arial,Helvetica,sans-serif">我是test下面的in.php</SPAN>
//需要重載__autoload方法,自定義包含類文件的路徑
function__autoload($classname)
{
$class_file=strtolower($classname).".php";
if(file_exists($class_file)){
require_once($class_file);
}
}
@$test=newin();//執(zhí)行到這里會(huì)輸出我是test下面的in.php沒(méi)問(wèn)題,成功了!我們還可以創(chuàng)建其他的文件來(lái)進(jìn)行加載,但是當(dāng)需要的文件很多需要區(qū)分目錄的時(shí)候怎么辦?
這時(shí)我們需要修改loader.php可以使用映射來(lái)找到要加載的文件。
[php]
function__autoload($class_name){
$map=array(
'index'=>'./include/index.php',
'in'=>'./in.php'
);
if(file_exists($map[$class_name])&&isset($map[$class_name])){
require_once$map[$class_name];
}
}
newindex();
function__autoload($class_name){
$map=array(
'index'=>'./include/index.php',
'in'=>'./in.php'
);
if(file_exists($map[$class_name])&&isset($map[$class_name])){
require_once$map[$class_name];
}
}
newindex();
這種方法的好處就是類名和文件路徑只是用一個(gè)映射來(lái)維護(hù),所以當(dāng)文件結(jié)構(gòu)改變的時(shí)候,不需要修改類名,只需要將映射中對(duì)應(yīng)的項(xiàng)修改就好了。
但是__autoload在一個(gè)項(xiàng)目中只能使用一次,當(dāng)你的項(xiàng)目引用了別人的一個(gè)項(xiàng)目,你的項(xiàng)目中有一個(gè)__autoload,別人的項(xiàng)目也有一個(gè)__autoload,這樣兩個(gè)__autoload就沖突了.解決的辦法就是修改__autoload成為一個(gè),這無(wú)疑是非常繁瑣的,應(yīng)用場(chǎng)景單一。
spl的autoload加載實(shí)現(xiàn):
spl的autoload系列函數(shù)使用一個(gè)autoload調(diào)用堆棧,你可以使用spl_autoload_register注冊(cè)多個(gè)自定義的autoload函數(shù),應(yīng)用場(chǎng)景廣泛