PHP 提供兩種自動載入機制:傳統的 __autoload() 魔術函數與現代標準的 spl_autoload_register()。本文系統梳理兩者差異、運作原理,並提供一個支援多目錄、多命名規則的生產級自動載入器實作範例。
| 特性 | __autoload() | spl_autoload_register() |
|---|---|---|
| 支援多載入器 | 否,全域僅一個 | 是,可註冊多個,按順序嘗試 |
| 命名空間支援 | 需自行解析 | 配合 PSR-0/PSR-4 標準極佳 |
| 預設實作 | 無 | 有 spl_autoload() (支援 .php/.inc) |
| 推薦程度 | 已棄用 (PHP 7.2+) | 現代標準,強烈推薦 |
function __autoload($className) {
if (file_exists($className . '.php')) {
include $className . '.php';
} else {
die($className . '.php is not exists.');
}
}
$controller = new IndexController(); // 觸發自動載入
// 使用內建預設載入器 (支援 .php, .inc)
spl_autoload_register();
$index = new Index();
// 註冊多個自訂載入器
function load1($className) { /* ... */ }
function load2($className) { /* ... */ }
spl_autoload_register('load1');
spl_autoload_register('load2');
// 依序嘗試 load1 -> load2
以下類別支援 Controller/Model/Helper/Library 四層目錄,對應不同命名後綴:
<?php
class Autoloader {
public static $loader;
public static function init() {
if (self::$loader === NULL) self::$loader = new self();
return self::$loader;
}
public function __construct() {
spl_autoload_register(array($this, 'model'));
spl_autoload_register(array($this, 'helper'));
spl_autoload_register(array($this, 'controller'));
spl_autoload_register(array($this, 'library'));
}
public function library($class) {
set_include_path(get_include_path() . PATH_SEPARATOR . '/lib/');
spl_autoload_extensions('.library.php');
spl_autoload($class);
}
public function controller($class) {
$class = preg_replace('/_controller$/ui', '', $class);
set_include_path(get_include_path() . PATH_SEPARATOR . '/controller/');
spl_autoload_extensions('.controller.php');
spl_autoload($class);
}
public function model($class) {
$class = preg_replace('/_model$/ui', '', $class);
set_include_path(get_include_path() . PATH_SEPARATOR . '/model/');
spl_autoload_extensions('.model.php');
spl_autoload($class);
}
public function helper($class) {
$class = preg_replace('/_helper$/ui', '', $class);
set_include_path(get_include_path() . PATH_SEPARATOR . '/helper/');
spl_autoload_extensions('.helper.php');
spl_autoload($class);
}
}
// 啟動
Autoloader::init();
?>
User_controller 映射至 controller/User.controller.php。