早期 require_once 'Class.php' 模式痛點:
自動加載 = 按需、延遲、約定式 載入類文件。
| 代數 | 機制 | 特點 | 狀態 |
|---|---|---|---|
| 第一代 | __autoload() | 全局函數、只能定義一次、項目/庫衝突 | PHP 7.2 棄用,8.0 移除 |
| 第二代 | spl_autoload_register() | 注冊多個加載器、棧式調用、支持匿名函數/類方法 | 核心底層 API,至今有效 |
| 第三代 | PSR-4 + Composer | 統一命名空間映射標準、自動生成加載器、生態標配 | ✅ 現代 PHP 唯一推薦 |
<?php
// 1. 注冊匿名函數加載器(簡單項目)
spl_autoload_register(function ($class) {
$file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php';
if (is_file($file)) require $file;
});
// 2. 注冊類靜態方法(模塊化)
class MyLoader {
public static function load(string $class): void {
// 映射邏輯...
}
}
spl_autoload_register([MyLoader::class, 'load']);
// 3. 優先級控制(預加載、覆蓋)
spl_autoload_register($loader, true, true); // $prepend=true 放棲頂
// 4. 異常處理:找不到類拋出 Exception 而非 Fatal Error
spl_autoload_register(function ($class) {
throw new Exception("Class $class not found");
});
完全限定類名:\Vendor\Package\SubNamespace\ClassName
│ │
└─ 命名空間前綴 ─┘ ← 映射到基礎目錄
│
└─ 相對路徑:SubNamespace/ClassName.php
規則:
\ 轉 /。.php),大小寫敏感。{
"autoload": {
"psr-4": {
"App\\": "src/",
"Vendor\\Package\\": "packages/package/src/"
},
"files": ["src/helpers.php"] // 全局函數文件
},
"autoload-dev": {
"psr-4": { "Tests\\": "tests/" }
}
}
composer dump-autoload -o # 生成優化加載器(生產環境)
# 入口文件
require __DIR__ . '/vendor/autoload.php';
use App\Controller\UserController;
$ctrl = new UserController(); // 自動載入 src/Controller/UserController.php
dump-autoload -o 生成 class -> file 映射表,無需文件系統查找,極快。composer dump-autoload --apcu 將映射存 APCu,跨進程共享。opcache.preload=preload.php 啟動時預載入熱門類,彌補無 JIT 的啟動開銷。App\\ 映射到多個目錄,導致衝突。-o 優化,開發環境可不加以便即時生效。現代 PHP 專案:composer.json 配置 psr-4 → dump-autoload -o → require vendor/autoload.php。忘掉 __autoload、手寫 spl_autoload_register,拥抱生態標準,專注業務邏輯。