## 类的自动加载
在编写面向对象(OOP)程序时,很多开发者为每个类新建一个 PHP 文件。这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)。
在 PHP 5 中,已经不再需要这样了。[spl\_autoload\_register()](https://www.php.net/manual/zh/function.spl-autoload-register.php)函数可以注册任意数量的自动加载器,当使用尚未被定义的类(class)和接口(interface)时自动去加载。通过注册自动加载器,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
> **Tip**
尽管 [\_\_autoload()](https://www.php.net/manual/zh/function.autoload.php) 函数也能自动加载类和接口,但更建议使用 [spl\_autoload\_register()](https://www.php.net/manual/zh/function.spl-autoload-register.php) 函数。 [spl\_autoload\_register()](https://www.php.net/manual/zh/function.spl-autoload-register.php) 提供了一种更加灵活的方式来实现类的自动加载(同一个应用中,可以支持任意数量的加载器,比如第三方库中的)。因此,不再建议使用 [\_\_autoload()](https://www.php.net/manual/zh/function.autoload.php) 函数,在以后的版本中它可能被弃用。
> **Note**:
> 在 PHP 5.3 之前,\_\_autoload 函数抛出的异常不能被 [catch](https://www.php.net/manual/zh/language.exceptions.php) 语句块捕获并会导致一个致命错误(Fatal Error)。 自 PHP 5.3 起,能够 thrown 自定义的异常(Exception),随后自定义异常类即可使用。 \_\_autoload 函数可以递归的自动加载自定义异常类。
> **Note**:
>
> 自动加载不可用于 PHP 的 CLI [交互模式](https://www.php.net/manual/zh/features.commandline.php)。
> **Note**:
> 如果类名比如被用于 [call\_user\_func()](https://www.php.net/manual/zh/function.call-user-func.php),则它可能包含一些危险的字符,比如 *../*。 建议您在这样的函数中不要使用用户的输入,起码需要在 [\_\_autoload()](https://www.php.net/manual/zh/function.autoload.php) 时验证下输入。
**Example #1 自动加载示例**
本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 *MyClass1* 和 *MyClass2* 类。
```
<?php
spl_autoload_register(function ($class_name) {
require_once $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
```
**Example #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 ...
*/
?>
```
以上例程会输出:
~~~
Want to load NonLoadableClass.
Unable to load NonLoadableClass.
~~~
**Example #4 自动加载在 PHP 5.3.0+ 中的异常处理 - 没有自定义异常机制**
本例将一个异常抛给不存在的自定义异常处理函数。
```
<?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
~~~
- 序言
- 简介
- PHP是什么?
- PHP能做什么?
- 基本语法
- 类型
- boolean(布尔型)
- integer(整型)
- float(浮点型)
- string(字符串)
- array(数组)
- object(对象)
- callable(可调用)
- resource(资源)
- NULL(无类型)
- 伪类型
- 类型转换的判别
- 变量
- 基础
- 预定义变量
- 变量范围
- 可变变量
- 来自PHP之外的变量
- 常量
- 语法
- 魔术常量
- 表达式
- 运算符
- 运算符优先级
- 算术运算符
- 赋值运算符
- 位运算符
- 比较运算符
- 错误控制运算符
- 执行运算符
- 递增/递减运算符
- 逻辑运算符
- 字符串运算符
- 数组运算符
- 类型运算符
- 流程控制
- if
- else
- elseif/else if
- 流程控制的替代语法
- while
- do-whille
- for
- foreach
- break
- continue
- switch
- declare
- return
- require
- include
- require_once
- include_once
- goto
- 函数
- 用户自定义函数
- 函数的参数
- 返回值
- 可变函数
- 内部 (内置)函数
- 匿名函数
- 类与对象
- 简介
- 基本概念
- 属性
- 类的自动加载
- 构造函数
- 访问控制(可见性)