PHP 5 前需手動 include/require,極其繁瑣。PHP 5 引入 __autoload() 魔術方法,PHP 5.1.2 新增 spl_autoload_register() 支援多載入器,PHP 5.3 命名空間普及後確立 PSR-4 為社區標準。
// A.php場景二:自定義載入函數名
function myLoader($class) { $file = $class . '.php'; if (is_file($file)) require_once $file; } spl_autoload_register('myLoader'); // 註冊,覆蓋 __autoload $a = new A();場景三:靜態類別方法載入(推薦)
class Loader { public static function loadClass($class) { $file = $class . '.php'; if (is_file($file)) require_once $file; } } spl_autoload_register(['Loader', 'loadClass']); // 類方法註冊 $a = new A();實戰模式:Discuz 風格兼容註冊
if (function_exists('spl_autoload_register')) { // PHP 5.1.2+ 註冊自定義載入器 spl_autoload_register(['core', 'autoload']); } else { // 降級:重寫 __autoload function __autoload($class) { return core::autoload($class); } }放在入口文件最頂部,確保全局生效。
PSR-4 標準:現代框架通用規範
核心規則:
- 完全限定類名:
\Vendor\Package\ClassName- 命名空間前綴對應基礎目錄
- 子命名空間對應子目錄
- 類名對應
.php文件PSR-4 載入器實現
class Psr4Autoloader { private $prefixes = []; public function addNamespace($prefix, $baseDir) { $prefix = trim($prefix, '\\') . '\\'; $baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $this->prefixes[$prefix][] = $baseDir; } public function register() { spl_autoload_register([$this, 'loadClass']); } public function loadClass($class) { foreach ($this->prefixes as $prefix => $dirs) { if (strpos($class, $prefix) === 0) { $relativeClass = substr($class, strlen($prefix)); $file = str_replace('\\', DIRECTORY_SEPARATOR, $relativeClass) . '.php'; foreach ($dirs as $dir) { $fullPath = $dir . $file; if (is_file($fullPath)) { require_once $fullPath; return true; } } } } return false; } } // 使用範例 $loader = new Psr4Autoloader(); $loader->addNamespace('App', __DIR__ . '/src'); $loader->addNamespace('Vendor\Package', __DIR__ . '/vendor/package/src'); $loader->register(); // 現在可以直接使用 $user = new \App\Model\User(); $service = new \Vendor\Package\Service();Composer 自動載入:生產環境標準
composer.json配置:{ "autoload": { "psr-4": { "App\\": "src/", "App\\Tests\\": "tests/" }, "files": ["src/helpers.php"] // 全局函數文件 } }執行
composer dump-autoload生成vendor/autoload.php,項目入口只需:require_once __DIR__ . '/vendor/autoload.php';常見陷阱與最佳實踐
| 問題 | 解決方案 |
|---|---|
| 大小寫敏感(Linux 區分大小寫) | 類名、文件名、命名空間嚴格統一大小寫(StudlyCaps) |
| 多載入器衝突 | 優先使用 Composer 統一管理,避免手動註冊多個 |
| 性能開銷 | 生產環境啟用 opcache.enable=1,Composer 生成 classmap 加速 |
| 開發環境調試 | 註冊調試載入器記錄載入路徑,排查找不到類問題 |