03-看官方文档学PHP面向对象-自动加载类

__autoload() 函数,它会在试图使用尚未被定义的类时自动调用。在 PHP 出错失败前有了最后一个机会加载所需的类。

TIP

spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

__autoload()方法

  1. 在 5.3.0 版之前,__autoload 函数抛出的异常不能被 catch 语句块捕获并会导致一个致命错误。从 5.3.0+ 之后,__autoload 函数抛出的异常可以被 catch 语句块捕获,但需要遵循一个条件。
  2. 如果抛出的是一个自定义异常,那么必须存在相应的自定义异常类。
  3. __autoload 函数可以递归的自动加载自定义异常类。
  4. 自动加载不可用于 PHP 的 CLI 交互模式
  5. 如果类名比如被用于 call_user_func(),则它可能包含一些危险的字符,比如 ../。 建议您在这样的函数中不要使用用户的输入,起码需要在 __autoload() 之前前验证下输入。
    If the class name is used e.g. in call_user_func() then it can contain some dangerous characters such as ../. It is recommended to not use the user-input in such functions or at least verify the input in __autoload().

自动加载示例

本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类

<?php
function __autoload($class_name) {
require_once $class_name . '.php';
//如果上面这行按照下面的写,你能在运行这段代码的时候发现,只输出了string(8) "MyClass1"
//这是因为"new MyClass1()"报错了.
//var_dump($class_name);

}
// 当前文件中不包含MyClass1的类声明,所以会自动调用魔术方法__autoload来加载
// 此时__autoload的参数是MyClass1,方法中具体怎么加载MyClass1?一般是用"require_once"来加载
$obj = new MyClass1(); // 报错:PHP Warning: require_once(MyClass1.php),我这里
// 说没找到,这是必然的,我整个测试就写了一个文件,当然没有这些类了.
$obj2 = new MyClass2(); //但这至少告诉我们__autoload的工作方式.
?>

自动加载方法里写var_dump输出结果

本例尝试加载接口 ITest。

<?php

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

class Foo implements ITest {
}

/*
运行时,网页显示:`string(5) "ITest"`,控制台报错:
127.0.0.1:46898 [500]: /01.php - Interface 'ITest' not found in /home/k3/桌面/test/01.php on line 7
*/
?>

自动加载在 PHP 5.3.0+ 中的异常处理

本例抛出一个异常并在 try/catch 语句块中演示。抛出异常后,控制台不再报错.

<?php
function __autoload($name) {
echo "Want to load $name.\n"; // 输出: "Want to load NonLoadableClass. \n"
// 如果注释下面这句,控制台就会报错了:
// "[500]: /01.php - Class 'NonLoadableClass' not found in /home/k3/桌面/test/01.php on line 8"
throw new Exception("Unable to load $name."); // 抛出错误 "Unable to load NonLoadableClass"
}

try {
$obj = new NonLoadableClass();
} catch (Exception $e) { // 捕获抛出的错误 "Unable to load NonLoadableClass"
echo $e->getMessage(), "\n"; // 显示捕获的错误,输出: "Unable to load NonLoadableClass"
}
?>

输出:

Want to load NonLoadableClass.
Unable to load NonLoadableClass.

自动加载在 PHP 5.3.0+ 中的异常处理 - 没有自定义异常机制

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

<?php
function __autoload($name) {
echo "Want to load $name.\n"; // 正常输出
throw new MissingException("Unable to load $name."); // 雷同上例,错误会被抛出,
// 同时在控制台会有报错:"[500]: /01.php - Class 'MissingException' not found in /home/k3/桌面/test/01.php on line 4"
}

try {
$obj = new NonLoadableClass();
} catch (Exception $e) {
echo $e->getMessage(), "\n"; //输出捕获到的错误信息"Unable to load NonLoadableClass"
}
?>

输出:

Want to load NonLoadableClass.
Want to load MissingException.

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

spl_autoload_register()函数

  1. 如果在你的程序中已经实现了autoload()函数,它必须显式注册到autoload()队列中。
  2. spl_autoload_register()会将Zend Engine中的__autoload()函数取代为spl_autoload()spl_autoload_call()
  3. spl_autoload_register()实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。

注册给定的函数作为 __autoload的实现,将函数注册到spl __autoload函数队列中。如果该队列中的函数尚未激活,则激活它们。
spl_autoload-__autoload()函数的默认实现,如果不使用
任何参数调用 autoload_register() 函数,则以后在进行 __autoload() 调用时会自动使用此函数。

说明:

bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )

参数

autoload_function

>欲注册的自动装载函数。如果没有提供任何参数,则自动注册 autoload 的默认实现函数spl_autoload()。

throw

>此参数设置了 autoload_function 无法成功注册时, spl_autoload_register()是否抛出异常。

prepend

>如果是 true,spl_autoload_register() 会添加函数到队列之首,而不是队列尾部。

返回值

成功返回true,失败返回false

范例

Example #1 spl_autoload_register() 作为 __autoload() 函数的替代

<?php

// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// }

function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
}

spl_autoload_register('my_autoloader');

// 或者,自 PHP 5.3.0 起可以使用一个匿名函数
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
});
?>

Example #2 class 未能加载的 spl_autoload_register() 例子

<?php

namespace Foobar;

class Foo {
static public function test($name) {
print '[['. $name .']]';
}
}

//将Foo::test这个静态方法用`spl_autoload_register()`装载到`spl_autoload()函数队列`
spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // 自 PHP 5.3.0 起

// 此时找不到这个类,于是引发自动加载,自动加载中有方法:`Foo::test`,该方法得到参数为InexistentClass,找不到该类,于是报错:
// `[500]: /01.php - Class 'Foobar\InexistentClass' not found in /home/k3/桌面/test/01.php on line 13`
new InexistentClass;

?>

看宁皓网视频学习自动加载类

设定项目目录为:test

设定要引入的类:’Track.php’

设定起始页:index.php

设定autoload文件:autoload.php

文件autoload.php的代码:

<?php
spl_autoload_register(
function($class){
$path = dirname(__FILE__) . '/' . $class . '.php';
if (file_exists($path)) {
require $path;
}
}
);

文件index.php

<?php
require_once 'autoload.php';
$track = new Track; // 遇到没定义的类,选择自动加载找该类
$track->name = "Foobar";
var_dump($track);
?>

文件Track.php

<?php
class Track
{
public $name;
}
?>
0%