php spl_autoload_register 与 __au

2019-08-19  本文已影响0人  云淡邀星

本文参考php官网和网上几篇优秀的博客,结合自己的理解,写了这篇文章,如有侵权,请联系作者删除。

一、首先看看__autoload的用法

__autoload

(PHP 5, PHP 7)
定义:__autoload — 尝试加载未定义的类
注意:该函数在php7.2已经弃用。
使用案例:
Hom类
./script/Hom.php
<?php
class Hom
{
    public function say()
    {
        echo "Hello Hom.".PHP_EOL;
    }
}
Scott类
./script/Scott.php
<?php
class Scott {
    public function say() {
        echo 'hello scott.'.PHP_EOL;
    }
}
autoload.php
./script/autoload.php
<?php
function __autoload($classname)
{
    $filename = "./". $classname. ".php";
    echo $classname.PHP_EOL;
    include_once($filename);
}

$hom = new Hom();
$scott = new Scott();
echo $hom->say();
echo $scott->say();

//$script2Hom = new Script2Hom();
// 下面的语句执行会报错,因为Script2Hom类与Hom或Scott类不在同个目录下,而__autoload()函数只是引入了Hom或Scott类所在的目录。
//echo $script2Hom->say();
执行autoload.php文件,结果如下:
[root@localhost script]# php autoload.php
Hom
Scott
Hello Hom.
hello scott.

二、再来看看spl_autoload_register()的用法

spl_autoload_register

(PHP 5 >= 5.1.0, PHP 7)
定义:spl_autoload_register — 注册给定的函数作为 __autoload 的实现
使用案例:
./script/spl.php
<?php
/**
 * spl_autoload_register($autoload_function, true, false)
 * 第一个参数:欲注册的自动装载函数。
 * 第二个参数:此参数设置了 autoload_function 无法成功注册时, spl_autoload_register()是否抛出异常。
 * 第三个参数:当为true时,spl_autoload_register()函数会添加函数到队列之首,而不是队列尾部。
 */
spl_autoload_register('autoload', true, true);

/**
 * 自定义类加载
 * @param string $className
 */
function autoload($className="") {
    echo "类名为:script/".$className . PHP_EOL;
    include "./{$className}.php";
}

$scott = new Scott();
$scott->say();

$script2Hom = new Script2Hom();
echo $script2Hom->say();
执行spl.php文件,结果如下:
[root@localhost script]# php spl.php
类名为:script/Scott
hello scott.

三、两个函数的主要区别:

如果需要多条 autoload 函数,spl_autoload_register() 满足了此类需求。 它实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。相比之下, __autoload() 只可以定义一次。
使用案例:
不同目录(script2)下的类文件Script2Hom.php
./script2/Script2Hom.php
<?php
class Script2Hom
{
    public function say()
    {
        echo "hello Script2Hom".PHP_EOL;
    }
}
spl2.php文件
./script/spl2.php
<?php
// spl_autoload_register可以注册加载多个自定义函数
spl_autoload_register('autoload', true, true);
spl_autoload_register('autoload2', true, true);

/**
 * 自定义类加载
 * @param string $className
 */
function autoload($className="") {
    echo "类名为:".$className . PHP_EOL;
    include "./{$className}.php";
}

function autoload2($className="") {
    echo "类名为:".$className . PHP_EOL;
    include "../script2/{$className}.php";
}

$hom = new Hom();
echo $hom->say();

$script2Hom = new Script2Hom();
echo $script2Hom->say();
执行spl2.php文件,结果如下:
[root@localhost script]# php spl2.php
类名为:Hom
类名为:Hom
Hello Hom.
类名为:Script2Hom
hello Script2Hom
在调用了spl_autoload_register()函数的前提下,如果在你的程序中已经实现了__autoload函数,它必须显式注册到__autoload栈中。因为spl_autoload_register()函数会将Zend Engine中的__autoload函数取代为spl_autoload()或spl_autoload_call()。
使用案例:
./script/spl3.php
<?php
spl_autoload_register('autoload', true, true);

/**
 * 在调用了spl_autoload_register()函数的前提下,如果在你的程序中已经实现了__autoload函数,它必须显式注册到         __autoload栈中。因为
    spl_autoload_register()函数会将Zend Engine中的__autoload函数取代为spl_autoload()或
    spl_autoload_call()。
 */
spl_autoload_register('__autoload', true, true);

/**
 * 自定义类加载
 * @param string $className
 */
function autoload($className="") {
    echo "类名为:script/".$className . PHP_EOL;
    include "./{$className}.php";
}

function __autoload($classname)
{
    $filename = "../script2/". $classname. ".php";
    echo "类名为:script2/".$classname.PHP_EOL;
    include_once($filename);
}

$scott = new Scott();
echo $scott->say();

$script2Hom = new Script2Hom();
echo $script2Hom->say();
执行spl3.php文件,结果如下:
[root@localhost script]# php spl3.php
类名为:script2/Scott
类名为:script/Scott
hello scott.
类名为:script2/Script2Hom
hello Script2Hom

总结不易,如有转载,请注明出处。

上一篇下一篇

猜你喜欢

热点阅读