类的自动加载

在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件。 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)。

spl_autoload_register() 函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

警告

PHP 8.0.0 之前,可以使用 __autoload() 自动加载类和接口。然而,它是 spl_autoload_register() 的一种不太灵活的替代方法,并且 __autoload() 在 PHP 7.2.0 起弃用,在 PHP 8.0.0 起移除。

示例 #1 自动加载示例

本例尝试分别从 MyClass1.phpMyClass2.php 文件中加载 MyClass1MyClass2 类。

<?php
spl_autoload_register
(function ($class_name) {
    require_once 
$class_name '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();
?>

示例 #2 另一个例子

本例尝试加载接口 ITest

<?php

spl_autoload_register
(function ($name) {
    
var_dump($name);
});

class 
Foo implements ITest {
}

/*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>

示例 #3 自动加载异常处理

本例抛出一个异常并在 try/catch 语句块中演示。

<?php
spl_autoload_register
(function ($name) {
    echo 
"Want to load $name.\n";
    throw new 
Exception("Unable to load $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

以上例程会输出:

Want to load NonLoadableClass.
Unable to load NonLoadableClass.

示例 #4 自动加载异常处理 - 没有自定义异常机制

本例将一个异常抛给不存在的自定义异常处理函数。

<?php
spl_autoload_register
(function ($name) {
    echo 
"Want to load $name.\n";
    throw new 
MissingException("Unable to load $name.");
});

try {
    
$obj = new NonLoadableClass();
} catch (
Exception $e) {
    echo 
$e->getMessage(), "\n";
}
?>

以上例程会输出:

Want to load NonLoadableClass.
Want to load MissingException.

Fatal error: Class 'MissingException' not found in testMissingException.php on line 4