| 函數 | 角色 | 特點 |
|---|---|---|
spl_autoload | SPL 內建默認加載器 | 功能簡單:將類名轉小寫,在 include_path 中查找 .inc 或 .php 文件(可通過 spl_autoload_extensions 自定義後綴)。 |
spl_autoload_call | 注冊加載器鏈的調度器 | 按順序執行注冊鏈中每個加載函數,任一成功即返回;全部失敗則靜默退出(不報錯)。 |
<?php
// 1. 設置類文件搜索路徑
set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/classes' . DIRECTORY_SEPARATOR);
// 2. 自定義文件後綴(可選)
spl_autoload_extensions('.php,.class.php,.inc');
// 3. 註冊 spl_autoload 到自動加載鏈
spl_autoload_register(); // 無參數時默認註冊 spl_autoload
?>
// 當代碼執行 new MyClass() 且類未定義時:
1. PHP 觸發自動加載機制
2. spl_autoload_call 依次調用注冊鏈中的函數:
- spl_autoload (若已註冊)
- 用戶自定義加載器 1
- 用戶自定義加載器 2
...
3. 某加載器成功 require 文件 → 類定義完成 → 返回
4. 所有加載器均失敗 → 拋出 Error: Class 'MyClass' not found
<?php
// PSR-4 聯合加載器示例
spl_autoload_register(function ($class) {
// 命名空間前綴映射
$prefix = 'App\\';
$base_dir = __DIR__ . '/src/';
if (strncmp($class, $prefix, strlen($prefix)) !== 0) {
return; // 不屬於本加載器管轄
}
$relative_class = substr($class, strlen($prefix));
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
// 也可註冊類方法
class Loader {
public static function load($class) { /* ... */ }
}
spl_autoload_register(['Loader', 'load']);
// 異常處理:加載失敗拋出異常而非報錯
spl_autoload_register(function ($class) {
if (!@include_once "classes/$class.php") {
throw new Exception("Class $class not found");
}
});
?>
spl_autoload_register('my_loader') 後又手動調用 spl_autoload() —— 重複加載,浪費性能。__autoload() —— PHP 7.2 棄用,8.0 移除,必須用 spl_autoload_register。Composer 生成的 vendor/autoload.php 內部註冊了多個加載器(PSR-4、PSR-0、Classmap、Files),完美演示了 spl_autoload_call 鏈式調度機制。