php自動(dòng)載方法有兩種.
創(chuàng)新互聯(lián)是一家企業(yè)級(jí)云計(jì)算解決方案提供商,超15年IDC數(shù)據(jù)中心運(yùn)營(yíng)經(jīng)驗(yàn)。主營(yíng)GPU顯卡服務(wù)器,站群服務(wù)器,綿陽(yáng)服務(wù)器托管,海外高防服務(wù)器,機(jī)柜大帶寬、租用·托管,動(dòng)態(tài)撥號(hào)VPS,海外云手機(jī),海外云服務(wù)器,海外服務(wù)器租用托管等。
第一種方案用__autoload,這個(gè)函數(shù)較簡(jiǎn)單,也較弱.
但有一問(wèn)題沒(méi)有解決, 就是在include前判斷文件是否存在的問(wèn)題.
set_include_path('aa'?.?PATH_SEPARATOR?.?get_include_path());
function?__autoload($className)
{
//如果加這個(gè)檢測(cè),?因?yàn)榇宋募辉诋?dāng)前目錄下,它就會(huì)檢測(cè)不到文件存在,?
//但include是能成功的
if?(file_exists($className?.?'.php'))?{
include_once($className?.?'.php');
}?else?{
exit('no?file');
}
}
$a?=?new?Acls();
第二種方案用spl自動(dòng)加載,這里具體說(shuō)一下這個(gè).
spl_autoload_register()
一個(gè)簡(jiǎn)單的例子
set_include_path('aa'?.?PATH_SEPARATOR?.?get_include_path());
//function?__autoload($className)
//{
//????if?(file_exists($className?.?'.php'))?{
//????????include_once($className?.?'.php');
//????}?else?{
//????????exit('no?file');
//????}
//}
spl_autoload_register();
$a?=?new?Acls();
傳統(tǒng)上,在PHP里,當(dāng)我們要用到一個(gè)class文件的時(shí)候,我們都得在文檔頭部require或者include一下:
?php
require_once('../includes/functions.php');
require_once('../includes/database.php');
require_once('../includes/user.php');
...
但是一旦要調(diào)用的文檔多了,就得每次都寫(xiě)一行,瞅著也不美觀,有什么辦法能讓PHP文檔自動(dòng)加載呢?
?php
function
__autoload($class_name)
{
require
"./{$class_name}.php";
}
對(duì),可以使用PHP的魔法函數(shù)__autoload(),上面的示例就是自動(dòng)加載當(dāng)前目錄下的PHP文件。當(dāng)然,實(shí)際當(dāng)中,我們更可能會(huì)這么來(lái)使用:
?php
function
__autoload($class_name)
{
$name
=
strtolower($class_name);
$path
=
"../includes/{$name}.php";
if(file_exists($path)){
require_once($path);
}else{
die("the
file
{$class_name}
could
not
be
found");
}
}
也即是做了一定的文件名大小寫(xiě)處理,然后在require之前檢查文件是否存在,不存在的話(huà)顯示自定義的信息。
類(lèi)似用法經(jīng)常在私人項(xiàng)目,或者說(shuō)是單一項(xiàng)目的框架中見(jiàn)到,為什么呢?因?yàn)槟阒荒芏x一個(gè)__autoload
function,在多人開(kāi)發(fā)中,做不到不同的developer使用不同的自定義的autoloader,除非大家都提前說(shuō)好了,都使用一個(gè)__autoload,涉及到改動(dòng)了就進(jìn)行版本同步,這很麻煩。
也主要是因?yàn)榇?,有個(gè)好消息,就是這個(gè)__autoload函數(shù)馬上要在7.2版本的PHP中棄用了。
Warning
This
feature
has
been
DEPRECATED
as
of
PHP
7.2.0.
Relying
on
this
feature
is
highly
discouraged.
那么取而代之的是一個(gè)叫spl_autoload_register()的東東,它的好處是可以自定義多個(gè)autoloader.
//使用匿名函數(shù)來(lái)autoload
spl_autoload_register(function($class_name){
require_once('...');
});
//使用一個(gè)全局函數(shù)
function
Custom()
{
require_once('...');
}
spl_autoload_register('Custom');
//使用一個(gè)class當(dāng)中的static方法
class
MyCustomAutoloader
{
static
public
function
myLoader($class_name)
{
require_once('...');
}
}
//傳array進(jìn)來(lái),第一個(gè)是class名,第二個(gè)是方法名
spl_autoload_register(['MyCustomAutoloader','myLoader']);
//甚至也可以用在實(shí)例化的object上
class
MyCustomAutoloader
{
public
function
myLoader($class_name)
{
}
}
$object
=
new
MyCustomAutoloader;
spl_autoload_register([$object,'myLoader']);
值得一提的是,使用autoload,無(wú)論是__autoload(),還是spl_autoload_register(),相比于require或include,好處就是autoload機(jī)制是lazy
loading,也即是并不是你一運(yùn)行就給你調(diào)用所有的那些文件,而是只有你用到了哪個(gè),比如說(shuō)new了哪個(gè)文件以后,才會(huì)通過(guò)autoload機(jī)制去加載相應(yīng)文件。
當(dāng)然,laravel包括各個(gè)package里也是經(jīng)常用到spl_autoload_register,比如這里:
/**
*
Prepend
the
load
method
to
the
auto-loader
stack.
*
*
@return
void
*/
protected
function
prependToLoaderStack()
{
spl_autoload_register([$this,
'load'],
true,
true);
}
php 中有個(gè)魔術(shù)方法__autoload ,這個(gè)函數(shù)在找不到類(lèi)的時(shí)候就會(huì)調(diào)用,自動(dòng)加載就是在這里實(shí)現(xiàn)的。通過(guò)指定自動(dòng)加載類(lèi)的路徑,只要保證文件名和類(lèi)名一樣。就可以自動(dòng)加載。這也是為什么你看很多源碼中類(lèi)的名字和文件名一樣的原因,這樣可以實(shí)現(xiàn)自動(dòng)加載,不需要include.