首頁 php教程 php手册 【PHP】__autoload()魔術方法與spl_autoload_register

【PHP】__autoload()魔術方法與spl_autoload_register

Sep 02, 2016 am 08:42 AM

參考連結:

1、spl_autoload_register與autoload的區別詳解

2、php.net 自動載入類別

 

很多開發者寫物件導向的應用程式時對每個類別的定義建立一個 PHP 原始檔。一個很大的煩惱是必須在每個腳本開頭寫一個長長的包含檔案清單(每個類別一個檔案)。

在 PHP 5 中,不再需要這樣了。可以定義一個 __autoload() 函數,它會在試圖使用尚未定義的類別時自動呼叫。透過呼叫此函數,腳本引擎在 PHP 出錯失敗前有了最後一個機會載入所需的類別。

 

簡單的引入範例:

先新建一個類別檔案MyClass.class.php:

<?php

class MyClass
{
    public function __construct()
    {
        echo "This is MyClass's construct";
    }

}
登入後複製

 

再在同目錄下新建任意名字的php檔案:

<?php

function __autoload($cls){
    var_dump($cls);
    require './'.$cls.".class.php";
}

$o1 = new MyClass();
// 这里不会再执行__autoload了,因为这个类已经require进来了。只有在当前文件中找不到该类的时候才会调用__autoload函数
$o2 = new MyClass();
登入後複製

這裡將require的內容放在了__autoload()中,如果沒有定義這個函數,會報一個致命錯誤(Fatal),提示找不到MyClass類別。

而定義了這個魔術方法會在new一個物件且在當前程式碼中找不到這個類別定義的時候(滿足以上2個條件),__autoload()函數被傳入一個類別名稱參數,並執行函數代碼段。

所以,在函數中執行了var_dump("MyClass");和require './MyClass.class.php';

 

結果如下:

string(7) "MyClass" This is MyClass's constructThis is MyClass's construct
登入後複製

這裡輸出了一次var_dump的內容和兩次建構子echo的內容。可以證明,當require進來之後,再次new MyClass這個類,並不會再呼叫__autoload()函數。

 

autoload有缺點:不能重複定義(PHP語言的特徵),導致如果要進行團隊開發的時候很不方便,容易出現衝突。

於是PHP 5.1.2之後有一個autoload註冊函數spl_autoload_register,以下是此函數的一些說明:

將函數註冊到SPL __autoload函數佇列。如果該隊列中的函數尚未激活,則激活它們。

如果需要多個 autoload 函數,spl_autoload_register() 滿足了這類需求。 它實際上創建了 autoload 函數的佇列,按定義時的順序逐一執行。相較之下, __autoload() 只可以定義一次。

 

在PHP 5.3引入了命名空間之後,此函數的參數有多種形式:

spl_autoload_register('my_autoloader');    // my_autoloader是一个函数名

spl_autoload_register(array('Loader', 'loadClass'));  // 表示类内的静态方法,Loader::loadClass

// 或者,自 PHP 5.3.0 起可以使用一个匿名函数
spl_autoload_register(function ($class) {
    include 'classes/' . $class . '.class.php';
});

spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // 自 PHP 5.3.0 起,可以使用命名空间的形式
登入後複製

 

這個函數只需要在new物件之前呼叫即可。

 

以下是一個例子(測試以上4種形式):

<?php

// namespace Atl;   // 加了这句话报错了!

function my_autoloader($cls){
    echo "<br/>$cls - my_autoloader <br/>";
    require_once './MyClass1.class.php';
}

class Loader{

    public static function loadClass($cls){
        echo "<br/>$cls - Loader::loadClass <br/>";
        require_once './MyClass2.class.php';
    }

    public static function nspClass($cls){
        echo "<br/>$cls - Loader::nspClass <br/>";
        require_once './MyClass3.class.php';
    }

}

spl_autoload_register('my_autoloader');

$o1 = new MyClass1();

spl_autoload_register(array('Loader', 'loadClass'));

$o2 = new MyClass2();

// 版本检测
if(version_compare(PHP_VERSION, '5.3.0', '<'))  die("以下的两个测试需要PHP 5.3及以上");

spl_autoload_register(__NAMESPACE__ .'\Loader::nspClass');
$o3 = new MyClass3();

spl_autoload_register(function ($cls) {
    echo "<br/>$cls - anonymous function <br/>";
    require_once './MyClass4.class.php';
});

$o4 = new MyClass4();
登入後複製

 

輸出的結果如下(注意到查找的先後順序與註冊順序相同):

MyClass1 - my_autoloader 
This is MyClass1's construct
MyClass2 - my_autoloader 

MyClass2 - Loader::loadClass 
This is MyClass2's construct
MyClass3 - my_autoloader 

MyClass3 - Loader::loadClass 

MyClass3 - Loader::nspClass 
This is MyClass3's construct
MyClass4 - my_autoloader 

MyClass4 - Loader::loadClass 

MyClass4 - Loader::nspClass 

MyClass4 - anonymous function 
This is MyClass4's construct
登入後複製

 

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)