PHP Conference Japan 2024

spl_autoload_register

(PHP 5 >= 5.1.0, PHP 7, PHP 8)

spl_autoload_register將給定的函式註冊為 __autoload() 實作

描述

spl_autoload_register(?callable $callback = null, bool $throw = true, bool $prepend = false): bool

將函式註冊到 spl 提供的 __autoload 佇列。如果佇列尚未啟用,則會啟用它。

如果您的程式碼已存在 __autoload() 函式,則必須在 __autoload 佇列上明確註冊此函式。這是因為 spl_autoload_register() 將有效地使用 spl_autoload()spl_autoload_call() 取代 __autoload() 函式的引擎快取。

如果必須有多個自動載入函式,則 spl_autoload_register() 允許這樣做。它會有效地建立自動載入函式的佇列,並按照它們定義的順序依序執行。相比之下,__autoload() 只能定義一次。

參數

callback

正在註冊的自動載入函式。如果為 null,則會註冊 spl_autoload() 的預設實作。

callback(string $class): void

class 將不包含完整識別符號的前導反斜線。

throw

此參數指定當無法註冊 callback 時,spl_autoload_register() 是否應該拋出例外。

警告

從 PHP 8.0.0 開始,此參數會被忽略,如果設定為 false,則會發出通知。spl_autoload_register() 現在總是會在無效的引數上拋出 TypeError

prepend

如果為 true,則 spl_autoload_register() 會將自動載入器附加到自動載入佇列,而不是將其附加到末端。

傳回值

成功時傳回 true,失敗時傳回 false

更新日誌

版本 描述
8.0.0 callback 現在可以為 null。

範例

範例 #1 spl_autoload_register() 作為 __autoload() 函式的替代

<?php

// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
include
'classes/' . $class . '.class.php';
}

spl_autoload_register('my_autoloader');

// 或者,使用匿名函式
spl_autoload_register(function ($class) {
include
'classes/' . $class . '.class.php';
});

?>

範例 #2 spl_autoload_register() 範例,其中類別未載入

<?php

namespace Foobar;

class
Foo {
static public function
test($class) {
print
'[['. $class .']]';
}
}

spl_autoload_register(__NAMESPACE__ .'\Foo::test');

new
InexistentClass;

?>

上述範例將輸出類似於

[[Foobar\InexistentClass]]
Fatal error: Class 'Foobar\InexistentClass' not found in ...

範例 #3 提供的識別符號將不帶有前導反斜線

<?php

spl_autoload_register
(static function ($class) {
var_dump($class);
});

class_exists('RelativeName');
class_exists('RelativeName\\WithNamespace');
class_exists('\\AbsoluteName');
class_exists('\\AbsoluteName\\WithNamespace');

?>

上述範例將輸出

string(12) "RelativeName"
string(26) "RelativeName\WithNamespace"
string(12) "AbsoluteName"
string(26) "AbsoluteName\WithNamespace"

另請參閱

新增註解

使用者貢獻註解 25 個註解

206
a dot schaffhirt at sedna-soft dot de
15 年前
適用於具有命名空間類別的 PHP 5.3 使用者的好消息

當您建立一個符合包含類別的命名空間的子資料夾結構時,您甚至永遠不必定義自動載入器。

<?php
spl_autoload_extensions
(".php"); // 逗號分隔的清單
spl_autoload_register();
?>

建議所有類別僅使用一個副檔名。PHP(更確切地說是 spl_autoload)會為您完成其餘工作,甚至比語義上相同的自訂自動載入函式更快,例如這個:

<?php
function my_autoload ($pClassName) {
include(
__DIR__ . "/" . $pClassName . ".php");
}
spl_autoload_register("my_autoload");
?>

我使用以下設定比較了它們:有 10 個資料夾,每個資料夾有 10 個子資料夾,每個子資料夾有 10 個子資料夾,每個子資料夾包含 10 個類別。

為了載入並實例化這些 1000 個類別(無參數無動作建構函式),在一系列對每個方法進行 10 次命令列呼叫中,使用者定義的自動載入函式方法平均花費的時間比 spl_autoload 函式長 50 毫秒。

我製作這個基準測試,是為了確保我之後不會推薦一些可能被稱作「好用,但速度慢」的東西。

誠摯問候,
24
nemanja
7 年前
即使使用自動載入 (SPL),類別繼承似乎也無法運作。簡單來說,PHP 引擎無法找到父(繼承)類別。PHP 5.6 和 7.0 在這方面的行為完全相同,這就失去了自動載入的目的。

而且恕我直言,這很容易修正,因為自動載入器可以毫無問題地找到所有第一層級的類別,它只需要在父類別上也以相同的方式遞迴尋找即可。

<?php
//使用預設的 SPL 自動載入器,命名空間與目錄結構一對一對應,檔案名稱皆為小寫。
//這僅適用於第一層級的類別,對於繼承則無效,它無法找到父類別。
spl_autoload_register();

//如果你也想要自動載入父類別,這段程式碼很醜陋但可以運作。
spl_autoload_register(function ($class){
require_once
__DIR__ . '/' . strtolower(str_replace('\\', '/', $class) . '.php');
});
30
eyeofmidas at gmail dot com
9 年前
當從使用 __autoload() 切換到使用 spl_autoload_register 時,請記住,反序列化 session 可能會觸發類別查找。

這會如預期運作
<?php
session_start
();
function
__autoload($class) {
...
}
?>

當使用從 session 反序列化的類別時,這會導致「__PHP_Incomplete_Class_Name」錯誤。
<?php
session_start
();
function
customAutoloader($class) {
...
}
spl_autoload_register("customAutoloader");
?>

因此,您需要確保 spl_autoload_register 在呼叫 session_start() 之前完成。

正確
<?php
function customAutoloader($class) {
...
}
spl_autoload_register("customAutoloader");
session_start();
?>
43
(delphists) at (apollo) dot (lv)
13 年前
當將 spl_autoload_register() 與類別方法一起使用時,它似乎只能使用 public 方法,儘管它也可以使用 private/protected 方法,如果從類別內部註冊的話。
<?php

class ClassAutoloader {
public function
__construct() {
spl_autoload_register(array($this, 'loader'));
}
private function
loader($className) {
echo
'Trying to load ', $className, ' via ', __METHOD__, "()\n";
include
$className . '.php';
}
}

$autoloader = new ClassAutoloader();

$obj = new Class1();
$obj = new Class2();

?>

輸出
--------
Trying to load Class1 via ClassAutoloader::loader()
Class1::__construct()
Trying to load Class2 via ClassAutoloader::loader()
Class2::__construct()
15
iam at thatguy dot co dot za
9 年前
<?php

// 使用 SPL_AUTOLOAD_REGISTER 方法從多個目錄自動載入類別檔案的範例。
// 它會自動載入任何以 class.<classname>.php (小寫) 開頭的檔案,例如:class.from.php、class.db.php
spl_autoload_register(function($class_name) {

// 定義一個目錄陣列,依照優先順序排列以進行迭代。
$dirs = array(
'project/', // 專案特定類別 (+核心覆寫)
'classes/', // 核心類別範例
'tests/', // 單元測試類別,如果使用 PHP-Unit
);

// 迴圈遍歷每個目錄以載入所有類別檔案。它只會載入檔案一次。
// 如果在後面的目錄中找到相同的類別,它會忽略它!因為只會載入一次!
foreach( $dirs as $dir ) {
if (
file_exists($dir.'class.'.strtolower($class_name).'.php')) {
require_once(
$dir.'class.'.strtolower($class_name).'.php');
return;
}
}
});
8
kuzawinski dot marcin at nospam dot gmail dot com
3 年前
由於 PHP 8.0,spl_autoload_register() 在引數無效時總是會擲回 TypeError,因此第二個引數 `throw` 會被忽略,如果設定為 False,則會發出通知。
19
florent at mediagonale dot com
18 年前
如果您的自動載入函式是類別方法,您可以使用指定類別和要執行方法的陣列來呼叫 spl_autoload_register。

* 您可以使用靜態方法
<?php

class MyClass {
public static function
autoload($className) {
// ...
}
}

spl_autoload_register(array('MyClass', 'autoload'));
?>

* 或者您可以使用實例
<?php
class MyClass {
public function
autoload($className) {
// ...
}
}

$instance = new MyClass();
spl_autoload_register(array($instance, 'autoload'));
?>
19
anthon at piwik dot org
14 年前
從已註冊的自動載入器擲回例外時請三思。

如果您已註冊多個自動載入器,而且其中一個(或多個)在稍後的自動載入器載入類別之前擲回例外,即使類別已成功載入,也會擲回堆疊的例外(而且必須被捕獲)。
16
a dot schaffhirt at sedna-soft dot de
11 年前
我之前在這裡說的只適用於 Windows。當您呼叫 spl_autoload_register() 而不帶任何引數時註冊的內建預設自動載入器,只是將限定類別名稱加上已註冊的檔案副檔名 (.php) 新增到每個包含路徑,然後嘗試包含該檔案。

範例 (在 Windows 上)

包含路徑
- "."
- "d:/projects/phplib"

要載入的限定類別名稱
network\http\rest\Resource

以下是發生的情況

PHP 嘗試載入
'.\\network\\http\\rest\\Resource.php'
-> 找不到檔案

PHP 嘗試載入
'd:/projects/phplib\\network\\http\\rest\\Resource.php'
-> 找到並包含檔案

請注意檔案路徑中的斜線和反斜線。在 Windows 上,這可以完美運作,但在 Linux 機器上,反斜線無法運作,而且檔案名稱會區分大小寫。

這就是為什麼在 Linux 上,快速簡便的方法是將這些限定類別名稱轉換為斜線並轉換為小寫,然後將它們傳遞給內建的自動載入器,如下所示

<?php
spl_autoload_register
(
function (
$pClassName) {
spl_autoload(strtolower(str_replace("\\", "/", $pClassName)));
}
);
?>

但這表示您必須以小寫檔案名稱儲存所有類別。否則,如果您省略 strtolower 呼叫,您必須完全按照檔案名稱指定的名稱來使用類別名稱,這對於以非直接大小寫定義的類別名稱(例如 XMLHttpRequest)來說可能很麻煩。

我比較喜歡小寫的方法,因為它更容易使用,而且檔案名稱轉換可以在部署時自動完成。
22
Anonymous
14 年前
在區分大小寫的檔案系統上使用此函式時請小心。

<?php
spl_autoload_extensions
('.php');
spl_autoload_register();
?>

我在 OS X 上開發,一切運作正常。但是當發布到我的 Linux 伺服器時,我的類別檔案都沒有載入。我必須將所有檔案名稱設為小寫,因為呼叫類別 "DatabaseObject" 會嘗試包含 "databaseobject.php",而不是 "DatabaseObject.php"

我想我會回去使用速度較慢的 __autoload() 函式,這樣我才能保持類別檔案的可讀性
2
abhijeet dot sweden at gmail dot com
2 年前
類型 #1

<?php

require_once('Second.php');
require_once(
'First.php');

$Second = new Second;
$Second->run_second();

$First = new First;
$First->run_first();

?>

---------------------------------------------------------
類型#2

<?php

spl_autoload_register
(function($class){
//
require_once($class.'.php');
});

$Second = new Second;
$Second->run_second();

$First = new First;
$First->run_first();

?>
6
rayro at gmx dot de
14 年前
在自動載入函式中使用 eval 來建立類別絕對不是個好主意,而且是個不合理的概念。
使用這些例外處理會是個不錯的功能,但我認為即使沒有這種方法,任何人都能處理它。目前我還沒意識到這有什麼好處...

我可能需要指出,class_exists() 將永遠定義您只想檢查其是否存在的類別,因此永遠會回傳 true。
<?php
function EvalIsEvil($class) {
eval(
'class '.$className.'{}');
}
spl_autoload_register('EvalIsEvil');
if (
class_exists($s="IsMyModuleHere")) {
// 這不是模組,但透過 eval() 取得...
return new $s();
}
?>
4
phil at propcom dot co dot uk
11 年前
重要的是要注意,如果 E_STRICT 錯誤觸發了錯誤處理常式,而該錯誤處理常式又嘗試使用尚未載入的類別,則不會呼叫自動載入器。

在這種情況下,您應該手動載入錯誤處理常式所需的類別。
3
rnealxp at yahoo dot com
7 年前
我現在使用 spl_autoload_register,而且沒有回頭路了。所以讓我在此為您總結我所學到的...
1.) 這些文件中提到的關於檔案名稱大小寫敏感性 (Windows 與 Linux/Mac) 的問題:只有在您在呼叫 spl_autoload_register 時,沒有提供自己的自訂函式作為引數時才會發生。您的函式要接受一個單一引數,這將是您的程式碼目前嘗試存取的類別名稱。我觀察到類別名稱的字母大小寫與您在程式碼庫中實際使用的大小寫相同 (混合大小寫或非混合大小寫)。我沒有在做/使用命名空間,但作為最佳實踐,為了讓您的實作簡單明瞭且可預測,請使用 fileName===className (1:1)。
2.) 我經常在我的程式碼庫變形時重構我的程式碼庫目錄結構。我沒有使用命名空間,但即使我有使用,我也會希望我的命名空間階層結構與我的目錄結構階層結構解耦。我喜歡我的目錄階層結構對於找到我想要使用的程式碼來說是直觀的。為了避免必須手動告知我的自動載入器每個檔案/類別的路徑,我會在靜態變數中快取幾個陣列,這些陣列只將檔案/類別名稱儲存在一個陣列中,並將檔案的資料夾路徑儲存在另一個陣列中。在第一次呼叫我的函式時設定快取 (靜態變數) 後,就只需要在檔案名稱陣列中查找即可。為了安全起見,並且為了避免問題,所有目錄階層結構 (您的命名空間) 中不應有兩個相同的 php 檔案名稱 - 我無論如何都喜歡這種做法,因此,我喜歡我的單一命名空間中使用唯一的類別名稱 (儘管它尚未明確定義)。我確實在我的函式中建立了一個檢查,以確保所有 php 檔案名稱/類別都是唯一的。
3.) 我將許多曾經在全域空間中具有函式集的檔案轉換為具有私有靜態變數和方法,當然也有公用靜態方法的 *抽象類別*。因此,這些函式集現在被封裝在物件中,而這些物件現在可以自動載入。僅僅為了這個好處,我再也不會在全域空間中使用函式,除了我的自動載入器函式和其他例外情況之外。
4.) 我的自動載入器函式僅使用內建的 php 語言結構和操作,沒有外部相依性。
5.) 如果您在程式碼庫中的某處使用函式 class_exists(),請注意,除非您將第二個引數傳遞為 false,否則您將觸發自動載入器來載入該類別。我當然偶然發現了這個。我的用例是我不希望載入該類別:我只想在類別被使用時 (在錯誤處理常式方法中) 採取一些動作。
6.) 如果您使用函式 method_exists(),您絕對會觸發載入類別 (這是合理的,因為您已經決定深入尋找特定的方法)。
7.) 我要歸功於這裡其他人的想法:我也選擇在應該存在的情況下,針對載入的類別呼叫 init() 方法。這可以避免我必須從外部手動呼叫,更不用說管理應該如何以及從何處進行呼叫。以這種自動化的方式設置物件並準備好工作非常有用。
8.) 如另一位所說,我也使用 require() 而不是 require_once(),因為前者足以產生錯誤,而且如果已載入,則不會呼叫該函式。
9.) 如果由於某種原因,我無法在我的快取陣列中找到類別名稱,我仍然會故意呼叫 require(),傳遞我沒有考慮到的類別名稱,以便產生並揭露問題 (當然,這不是預期的!)。
10.) 再次強調,我確保所有類別名稱的唯一性。如果我觀察到非唯一性,我會再次對 require() 進行錯誤的呼叫,如下所示:require('FoundMultiplesOfClassFile.php'); 以揭露問題。(我還沒有,而且您可能也不應該註冊任何複雜的錯誤處理常式,因此對我來說,這和其他方法一樣好)。
2
daniel at amnistechnology dot com
12 年前
我巧妙地 - 且實用地 - 注意到 (至少在 PHP 5.3 上),即使您呼叫尚未載入的所有靜態類別的公用靜態方法,這些自動載入器也會「啟動」。
4
sebastian dot krebs at kingcrunch dot de
14 年前
似乎 spl_autoload 會在呼叫每個註冊的載入器後測試類別是否存在。因此,如果類別存在,它會中斷鏈,並且不會呼叫其他載入器。

<?php
function a ($c) {
echo
"a\n";
class
Bla {} // 通常是 "include 'path/to/file.php';"
}
function
b ($c) {
echo
"b\n";
}
spl_autoload_register('a');
spl_autoload_register('b');

$c = new Bla();
?>
-1
Daniel Klein
2 年前
如果您想要能夠從任何地方執行您的 PHP 腳本,而無需先變更目錄,請在您執行的第一個檔案中使用 chdir(__DIR__) (而不是任何包含檔案)。

<?php
spl_autoload_register
();
chdir(__DIR__);

由於某些原因嘗試從其他命名空間的類別中使用命名空間的類別會失敗

例如執行"php src/main.php"會失敗"cd src && php main.php"會正常運作

src/main.php
<?php
spl_autoload_register
();
//chdir(__DIR__); // 取消註解此行以使其從任何目錄正常運作
MyNamespace\MyClass::foo();

src/MyNamespace/MyClass.php
<?php
namespace MyNamespace;

class
MyClass {
public static function
foo(): void {
echo
MyOtherClass::BAR; // 即使 MyOtherClass.php 在正確的位置,也會失敗
}
}

src/MyNamespace/MyOtherClass.php
<?php
namespace MyNamespace;

class
MyOtherClass {
public const
BAR = 'baz';
}
0
kakkau at grr dot la
9 年前
關於註冊帶有額外參數的自動載入函式的注意事項。

./alf.home.php
<?php
/*
* 包含自動載入函式別名 ALF 的類別:)
*/
class ALF {
public function
haaahaaahaaa($class = "ALF", $param = "Melmac") {
echo
"我是 ".$class." 來自 ".$param.".\n";
}
}
?>

./kate.melmac.php
<?php
require_once("alf.home.php");
/*
* 通常的方法是取得 ALF
* 並註冊一個自動載入函式
*/
$alf = new ALF();
spl_autoload_register(array($alf,'haaahaaahaaa'));
$alf->haaahaaahaaa(); // ALF 來自 Melmac :)
/*
* 現在讓我們嘗試自動載入一個類別
*/
@$kate = new Kate(); // 這會拋出嚴重錯誤,因為
// Kate 不是來自 Melmac :)
?>
我是 ALF 來自 Melmac。
我是 Kate 來自 Melmac。

./kate.earth.php
<?php
require_once("alf.home.php");
/*
* 但是如果我們想更正 Kate 的來源呢?
* 如何在註冊時將參數傳遞給自動載入函式?
*
* spl_autoload_register 不適合這樣做
* 但我們可以嘗試在註冊期間定義一個可呼叫的函式
*/
spl_autoload_register(function($class){
call_user_func(array(new ALF(),'haaahaaahaaa'), $class, "Earth"); });
/*
* 現在讓我們再次嘗試自動載入一個類別
* Kate 仍然找不到,但我們更正了她的來源 :)
*/
@$kate = new Kate(); // Kate 來自 Earth :)
/*
* 注意:您無法使用
* 上面的註冊方法,在可呼叫的環境之外傳遞 $this 或其他建立的物件。
* 因此,您應該將自動載入函式交換為一個單獨的類別,如開頭使用 ALF 所做的那樣。
*
* 注意:您可能無法直接取消註冊自動載入函式
* 因為執行個體是在另一個環境中建立的
*/
?>
我是 Kate 來自 Earth。
0
stanlemon at mac dot com
17 年前
編輯註記:請求此函式模擬的行為的適當 PHP 錯誤是 http://bugs.php.net/bug.php?id=42823 。如果自動載入堆疊中註冊了 array($obj, 'nonStaticMethod'),則此函式將無法運作——雖然會移除自動載入,但會不正確地重新註冊。

spl_autoload_register() 方法會按照呼叫 spl_autoload_register() 的順序在其堆疊中註冊函式,隨後如果您希望自動載入函式覆蓋先前的自動載入函式,您需要取消註冊先前的函式或變更自動載入堆疊的順序。

例如,假設在自動載入函式的預設實作中,如果找不到類別,您會拋出例外狀況,或者可能會發生嚴重錯誤。稍後在您的程式碼中,您會新增自動載入函式的第二個實作,該實作會載入先前方法會失敗的程式庫。這不會先呼叫第二個自動載入器方法,而是會繼續在第一個方法中發生錯誤。

如先前所述,您可以取消註冊現有的會發生錯誤的自動載入器,或者您可以建立一種機制來取消註冊並按照您想要的順序重新註冊自動載入器。

這是一個範例/範例,說明您可能會考慮如何重新註冊自動載入器,以便先呼叫最新的自動載入器,最後呼叫最舊的自動載入器

<?php

// 編輯註記:新增至函式的小錯誤和相容性修正
//
function spl_autoload_preregister( $autoload ) {
// 目前堆疊中沒有函式。
if ( ($funcs = spl_autoload_functions()) === false ) {
spl_autoload_register($autoload);
} else {
// 取消註冊現有的自動載入器...
$compat =
version_compare(PHP_VERSION, '5.1.2', '<=') &&
version_compare(PHP_VERSION, '5.1.0', '>=');
foreach (
$funcs as $func) {
if (
is_array($func)) {
// :TRICKY: 有一些相容性問題和一些
// 我們需要錯誤輸出的位置
$reflector = new ReflectionMethod($func[0], $func[1]);
if (!
$reflector->isStatic()) {
throw new
Exception('
此函式與非靜態物件方法不相容,因為 PHP Bug #44144。
'
);
}
// 令人驚訝的是,spl_autoload_register 支援
// Class::staticMethod 回呼格式,儘管 call_user_func 不支援
if ($compat) $func = implode('::', $func);
}
spl_autoload_unregister($func);
}

// 註冊新的自動載入器,從而將其置於堆疊的最前面...
spl_autoload_register($autoload);

// 現在,返回並重新註冊我們所有的舊自動載入器。
foreach ($funcs as $func) {
spl_autoload_register($func);
}
}
}

?>

注意:我沒有測試此方法的額外負荷,因此我不能 100% 確定以上範例的效能影響。
-1
harvey dot NO_SPAM dot robin at gmail dot com
17 年前
此函式非常聰明,不會重複新增相同的載入器。這似乎適用於所有不同的載入器格式。範例

<?php
class ALoader
{
static function
load($class) { return true; }
}

function
anotherLoader($class) {
return
true;
}

$F = new ALoader;

spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array('ALoader', 'load'));
spl_autoload_register(array($F, 'load'));
spl_autoload_register('anotherLoader');
spl_autoload_register('anotherLoader');
var_dump(spl_autoload_functions());

/*
* 在 PHP5.2 CLI (Linux) 上的結果。
* array(2) {
* [0]=>
* array(2) {
* [0]=>
* string(7) "ALoader"
* [1]=>
* string(4) "load"
* }
* [1]=>
* string(13) "anotherLoader"
* }
*/
?>
-1
n0mAd at example dot com
6 年前
如果您需要在使用命名空間時註冊函式,請使用 __NAMESPACE__ 常數來定義名稱。

<?php

namespace Foobar;

spl_autoload_register('MyFunction'); // 錯誤
spl_autoload_register('\MyFunction');// 錯誤
spl_autoload_register(__NAMESPACE__ . '\MyFunction'); // 正確

?>
-2
hajo-p
10 年前
如果您的目錄結構像 "/abc/def/ghi",您的 index.php 位於頂層目錄,但您想要使用以 "def" 或 "ghi" 開頭的命名空間

您可以使用例如 set_include_path(__DIR__ . '/abc') 來切換 PHP 的命名空間根目錄,然後使用簡單的 spl_autoload_register() 函數(不帶任何參數)來定義和使用您的命名空間。

請記住,PHP 處理器 "cli" 和 "cli-server" 是特殊情況。
-3
Kurd the Great
11 年前
if(!defined('BASE_PATH')) {
define('BASE_PATH', dirname(__FILE__) . '/');
require BASE_PATH . 'Autoloader.php';
Autoloader::Register();
}

class Autoloader
{
public static function Register() {
return spl_autoload_register(array('Autoloader', 'Load'));
}

public static function Load($strObjectName) {
if(class_exists($strObjectName) === false) {
return false;
}

$strObjectFilePath = BASE_PATH . $strObjectName . '.php';

if((file_exists($strObjectFilePath) === false) || (is_readable($strObjectFilePath) === false)) {
return false;
}

require($strObjectFilePath);
}
}
-2
joneschrisan at aol dot com
8 年前
看起來在最新的 Debian PHP 更新中,在 Linux 上不帶任何參數傳遞給 spl_autoload 已經不起作用了。

它無法將命名空間中的 \'s 替換為檔案路徑中的 /'s。
-3
neolium at gmail dot com
9 年前
如果您將每個類別都放在不同的檔案中,此自動載入器將會找到您呼叫的每個類別。

它會從您在 $root 變數中指定的根目錄開始,遞迴地進入每個目錄。

您可以在 $dir_to_not_look_in 陣列中指定您不想進入的資料夾 (例如,您不會在 MVC 專案的 'view' 資料夾中找到任何類別);

spl_autoload_register(function($class) {

$root = 'my/root/path';
$file = $class . '.php';
$dir_to_not_look_in = array($directories, $to, $not, $look, $in);

if(!function_exists('load')) {
function load($dir, $file) {
if(file_exists($dir . '/' . $file)) {
require_once $dir . '/' . $file;
} else {
foreach(scandir($dir) as $value) {
if(is_dir($dir. '/' . $value) && !in_array($value, $dir_to_no_look_in))
load($dir. '/' . $value, $file);
}
}
};
}

load($root, $file);

});
To Top