美文网首页
php spl_autoload_register 与 __au

php spl_autoload_register 与 __au

作者: 云淡邀星 | 来源:发表于2019-08-19 20:09 被阅读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
    

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

    相关文章

      网友评论

          本文标题:php spl_autoload_register 与 __au

          本文链接:https://www.haomeiwen.com/subject/llmesctx.html