__autoload,spl_autoload_register與自動加載
先介紹兩個函數
__autoload()函數:嘗試加載未定義的類;
函數聲明是
void __autoload(string $class)
參數$class是待加載的類名,無返回值
說明:定義了這個函數之後,如果調用了某一個類,但是這個類文件沒有加載進來(require,include),那麼就會自動調用__autoload()函數,類名就是函數參數(有時候還會帶着命名空間)
spl_autoload_register()函數:註冊給定的函數作爲 __autoload 的實現
函數聲明是
bool spl_autoload_register ([ callable$autoload_function [, bool $throw = true [, bool $prepend = false ]]] )
這裏只說第一個參數,這個參數是回調函數類型的,也就是會傳遞一個函數的名字給spl_autoload_register()函數
說明:該函數觸發規則和__autoload函數一樣,也是在沒有找到將要實例化的類時,被觸發。觸發時,使用參數裏的回調函數處理,回調函數參數爲類名。其實和__autoload()一樣,只不過,__autoload只能定義一次,而spl_autoload_register可多次使用。
兩個函數的例子對比
__autoload
spl_autoload_register
PS:spl_autoload_register產生的效果其實就是類似以下代碼
區別就在於,__autoload只能定義一次,而spl_autoload_register可多次使用,從而使得自動加載更加方便簡潔。
關於自動加載,其實很多框架都是使用spl_autoload_register與命名空間來實現的,下面的是thinkphp5的自動加載,可以嘗試理解
// 自動加載
public static function autoload($class)
{
// 檢測命名空間別名
if (!empty(self::$namespaceAlias)) {
$namespace = dirname($class);
if (isset(self::$namespaceAlias[$namespace])) {
$original = self::$namespaceAlias[$namespace] . '\\' . basename($class);
if (class_exists($original)) {
return class_alias($original, $class, false);
}
}
}
if ($file = self::findFile($class)) {
// Win環境嚴格區分大小寫
if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {
return false;
}
__include_file($file);
return true;
}
}
該代碼位於thinkphp\library\think\Loader.php裏,可自行查看