傳統 require_once 在腳本開頭載入所有類別檔案,隨專案增大會造成:
惰性載入(Lazy Loading)僅在真正需要類別時才載入,結合 ReflectionClass 與 SPL 自動載入機制,可實現優雅的按需載入。
<?php
// test.php
class Test {
public function showName() {
var_dump(__CLASS__);
}
}
// index.php
var_dump(get_included_files()); // 僅含 index.php
$rf = new ReflectionClass('Test'); // 此處觸發 __autoload
var_dump(get_included_files()); // 新增 test.php
$obj = $rf->newInstance();
$obj->showName(); // 輸出 string(4) "Test"
__autoload 已棄用(PHP 7.2+),應使用 spl_autoload_register 註冊多載入器:
<?php
// 自動載入器
spl_autoload_register(function ($class) {
$file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
});
// 使用
$user = new App\Models\User(); // 自動載入 src/App/Models/User.php
$order = new App\Services\OrderService(); // 自動載入對應檔案
<?php
class Container {
private static $instances = [];
private static $loaders = [];
public static function registerLoader(callable $loader) {
self::$loaders[] = $loader;
}
public static function get(string $class) {
if (!isset(self::$instances[$class])) {
// 嘗試自動載入
foreach (self::$loaders as $loader) {
if ($loader($class)) break;
}
if (!class_exists($class)) {
throw new RuntimeException("Class $class not found");
}
// 建立單例
$ref = new ReflectionClass($class);
self::$instances[$class] = $ref->newInstanceWithoutConstructor();
// 若有初始化方法
if (method_exists(self::$instances[$class], 'init')) {
self::$instances[$class]->init();
}
}
return self::$instances[$class];
}
}
// 註冊 PSR-4 載入器
Container::registerLoader(function($class) {
$file = __DIR__ . '/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
});
// 使用
$db = Container::get('App\Database\Connection');
$cache = Container::get('App\Cache\RedisCache');
手寫自動載入僅適合學習或微型專案。正式專案請直接使用 Composer:
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
執行 composer dump-autoload 產生 vendor/autoload.php,專案入口僅需 require 'vendor/autoload.php'; 即可享受高效能、標準化的自動載入。
| 方式 | 啟動時間 | 記憶體 | 適用場景 |
|---|---|---|---|
| require_all | 慢 | 高 | 極小專案、腳本 |
| __autoload | 中 | 中 | 舊專案維護 |
| spl_autoload_register | 快 | 低 | 中型專案、自訂邏輯 |
| Composer PSR-4 | 最快(含快取) | 最低 | 所有現代專案 |
file_exists + require 最快。理解 ReflectionClass 觸發自動載入的機制,有助於深入掌握 PHP 類別載入流程。但實務上,**請直接使用 Composer PSR-4**,專注於業務邏輯而非重造輪子。