最近在研究Composer的自动加载时,发现
spl_autoload_register()
这个函数非常重要,总结下。
spl_autoload_register()
的作用是 注册给定的函数作为 __autoload
的实现
spl_autoload_register()
函数是实现自动加载未定义类功能的的重要方法,所谓的自动加载意思就是 我们的new 一个类的时候必须先include或者require的类文件,如果没有include或者require,则会报错。那这样我们就必须在文件头部写上许多include或require文件,非常麻烦,为了使得没有include或者require类的时候也正常new一个类,所以有了自动加载的概念,也就是说new一个类之前不用事先包含类文件也可以正常new,这样我们的文件头部就不用包含许多include(require)。
用spl_autoload_register()
函数可以实现上面说的功能,我们来看看实现原理。这个函数的参数如下:
/**
* Register given function as __autoload() implementation
* @link https://php.net/manual/en/function.spl-autoload-register.php
* @param callback $autoload_function [optional] <p>
* The autoload function being registered.
* If no parameter is provided, then the default implementation of
* spl_autoload will be registered.
* </p>
* @param bool $throw This parameter specifies whether spl_autoload_register() should throw exceptions when the
* autoload_function cannot be registered.
* @param bool $prepend If true, spl_autoload_register() will prepend the autoloader on the autoload stack instead of
* appending it.
* @return bool true on success or false on failure.
* @since 5.1.2
*/
function spl_autoload_register ($autoload_function = null, $throw = true, $prepend = false) {}
$autoload_function
欲注册的自动装载函数。如果没有提供任何参数,则自动注册 autoload 的默认实现函数spl_autoload()
。
$throw
此参数设置了 autoload_function 无法成功注册时, spl_autoload_register()
是否抛出异常。
$prepend
如果是 true,spl_autoload_register()
会添加函数到队列之首,而不是队列尾部。
//文件 autoloadClass.php ,需要new的文件
class AutoloadClass{
public function __construct()
{
echo '你已经包含我了';
}
}
//文件autoloadDemo.php文件
spl_autoload_register('myAutoLoad', true, true);
function myAutoLoad($className){
echo "所有的包含文件工作都交给我!\r\n";
$classFileName = "./{$className}.php";
echo "我来包含!{$classFileName}\r\n";
include "./{$className}.php";
}
$objDemo = new AutoloadClass();
/**
输出:
所有的包含文件工作都交给我!
我来包含!./AutoloadClass.php
你已经包含我了
*/
如果需要多条 autoload 函数,spl_autoload_register()
满足了此类需求。 它实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。相比之下, __autoload()
只可以定义一次。
//文件autoloadDemo.php文件
spl_autoload_register('myAutoLoad', true, true);
function myAutoLoad($className){
echo "所有的包含文件工作都交给我!\r\n";
$classFileName = "./{$className}.php";
echo "我来包含!{$classFileName}\r\n";
include "./{$className}.php";
}
spl_autoload_register('myAutoLoad_1', true, true);
function myAutoLoad_1($className){
echo "所有的包含文件工作都交给我!\r\n";
$classFileName = "./{$className}.php";
echo "我来包含!{$classFileName}\r\n";
include "./{$className}.php";
}
var_dump(spl_autoload_functions());
/**
输出:
array(2) {
[0]=>
string(11) "myAutoLoad_1"
[1]=>
string(10) "myAutoLoad"
}
*/
spl_autoload_unregister()
— 注销已注册的__autoload()
函数
//文件autoloadDemo.php文件
spl_autoload_register('myAutoLoad', true, true);
function myAutoLoad($className){
echo "所有的包含文件工作都交给我!\r\n";
$classFileName = "./{$className}.php";
echo "我来包含!{$classFileName}\r\n";
include "./{$className}.php";
}
spl_autoload_unregister('myAutoLoad');
var_dump(spl_autoload_functions());
/**
输出:
所有的包含文件工作都交给我!
我来包含!./AutoloadClass.php
你已经包含我了
array(0) {
}
*/
关于__autoload()
函数
PHP7官方已经不再建议使用这个函数了,放弃吧,少年。