PHP 5 引入 __autoload() 魔術方法,當實例化未定義的類時自動觸發,避免手動 require/include。但 PHP 7.2 棄用,8.0 移除,現代項目應使用 spl_autoload_register() 或 Composer PSR-4 自動加載。
<?php
function __autoload($class_name) {
// 將類名中的下劃線轉為目錄分隔符
// 例:Http_File_Interface → Http/File/Interface.php
$path = str_replace('_', '/', $class_name);
$file = $path . '.php';
if (file_exists($file)) {
require_once $file;
}
}
// 使用時自動加載 Http/File/Interface.php
$obj = new Http_File_Interface();
?>
spl_autoload_register() 支持多個加載器、異常處理、優先級控制,是現代框架的基礎。
<?php
spl_autoload_register(function ($class) {
// 項目命名空間前綴
$prefix = 'App\\';
$base_dir = __DIR__ . '/src/';
// 僅處理本項目命名空間
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
// 獲取相對類名
$relative_class = substr($class, $len);
// 命名空間分隔符 → 目錄分隔符,類名 → 文件名
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
// 使用
$user = new App\Model\User();
$service = new App\Service\OrderService();
?>
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
// 執行 composer dump-autoload 後
require __DIR__ . '/vendor/autoload.php';
// 即可直接使用
$user = new App\Model\User();
| 特性 | __autoload | spl_autoload_register | Composer PSR-4 |
|---|---|---|---|
| 多加載器支持 | 否(僅一個) | 是 | 是 |
| 異常處理 | 困難 | 支持 | 完善 |
| 命名空間映射 | 手動字符串替換 | 手動實現 | 標準化配置 |
| PHP 版本支持 | 5.0-7.1(8.0 移除) | 5.1.2+ | 5.3.2+ |
| 生產環境推薦 | ❌ | ⚠️ 小項目 | ✅ 標準 |
建議:新項目直接使用 Composer PSR-4;維護舊項目時,將 __autoload 遷移至 spl_autoload_register 以兼容 PHP 8+。