课程咨询 :15610069419 QQ:2720475033

保险

  • __autoload()魔术方法与spl_autoload_register

    发布:青岛php培训      来源:青岛php培训      时间:2016-09-05

  • 很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含文件列表(每个类一个文件)。

    在 PHP 5 中,不再需要这样了。可以定义一个 __autoload() 函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

    简单的引入例子:

    __autoload()魔术方法与spl_autoload_register

    先新建一个类文件MyClass.class.php:

    class MyClass

    {

    public function __construct()

    {

    echo "This is MyClass's construct";

    }

    }

    再在同目录下新建任意名字的php文件:

    function __autoload($cls){

    var_dump($cls);

    require './'.$cls.".class.php";

    }

    $o1 = new MyClass();

    // 这里不会再执行__autoload了,因为这个类已经require进来了。只有在当前文件中找不到该类的时候才会调用__autoload函数

    $o2 = new MyClass();

    这里将require的内容放在了__autoload()中,如果没有定义这个函数,会报一个致命错误(Fatal),提示找不到MyClass类。

    而定义了这个魔术方法会在new一个对象 且 在当前代码中找不到这个类定义的时候(满足以上2个条件),__autoload()函数被传入一个类名参数,并执行函数代码段。

    所以,在函数中执行了var_dump("MyClass");和require './MyClass.class.php';

    结果如下:

    1string(7) "MyClass" This is MyClass's constructThis is MyClass's construct

    这里输出了一次var_dump的内容和两次构造函数echo的内容。可以证明,当require进来之后,再次new MyClass这个类,并不会再次调用__autoload()函数。

    autoload有缺点:不能重复定义(PHP语言的特点),导致如果要进行团队开发的时候很不方便,容易出现冲突。

    于是PHP 5.1.2之后有一个autoload注册函数spl_autoload_register,以下是此函数的一些说明:

    将函数注册到SPL __autoload函数队列中。如果该队列中的函数尚未激活,则激活它们。

    如果需要多条 autoload 函数,spl_autoload_register() 满足了此类需求。 它实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。相比之下, __autoload() 只可以定义一次。

    在PHP 5.3引入了命名空间之后,此函数的参数有多种形式:

    10spl_autoload_register('my_autoloader'); // my_autoloader是一个函数名

    spl_autoload_register(array('Loader', 'loadClass')); // 表示类内的静态方法,Loader::loadClass

    // 或者,自 PHP 5.3.0 起可以使用一个匿名函数

    spl_autoload_register(function ($class) {

    include 'classes/' . $class . '.class.php';

    });

    spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // 自 PHP 5.3.0 起,可以使用命名空间的形式

    这个函数只需要在new对象之前调用即可。

    以下是一个例子(测试以上4种形式):

    // namespace Atl; // 加了这句话报错了!

    function my_autoloader($cls){

    echo "

    $cls - my_autoloader

    ";

    require_once './MyClass1.class.php';

    }

    class Loader{

    public static function loadClass($cls){

    echo "

    $cls - Loader::loadClass

    ";

    require_once './MyClass2.class.php';

    }

    public static function nspClass($cls){

    echo "

    $cls - Loader::nspClass

    ";

    require_once './MyClass3.class.php';

    }

    }

    spl_autoload_register('my_autoloader');

    $o1 = new MyClass1();

    spl_autoload_register(array('Loader', 'loadClass'));

    $o2 = new MyClass2();

    // 版本检测

    if(version_compare(PHP_VERSION, '5.3.0', '<')) die("以下的两个测试需要PHP 5.3及以上");

    spl_autoload_register(__NAMESPACE__ .'\Loader::nspClass');

    $o3 = new MyClass3();

    spl_autoload_register(function ($cls) {

    echo "

    $cls - anonymous function

    ";

    require_once './MyClass4.class.php';

    });

    $o4 = new MyClass4();

    输出的结果如下(注意到查找的先后顺序与注册顺序相同):

    20MyClass1 - my_autoloader

    This is MyClass1's construct

    MyClass2 - my_autoloader

    MyClass2 - Loader::loadClass

    This is MyClass2's construct

    MyClass3 - my_autoloader

    MyClass3 - Loader::loadClass

    MyClass3 - Loader::nspClass

    This is MyClass3's construct

    MyClass4 - my_autoloader

    MyClass4 - Loader::loadClass

    MyClass4 - Loader::nspClass

    MyClass4 - anonymous function

    This is MyClass4's construct

上一篇:PHP常用文件函数和目录函数整理

下一篇:接口调用,字符串截取处理

最新开班日期  |  更多

PHP高级开发工程师就业班

PHP高级开发工程师就业班

开班日期:9月28日

PHP高级开发工程师精品班

PHP高级开发工程师精品班

开班日期:9月28日

PHP高级开发工程师周末班

PHP高级开发工程师周末班

开班日期:9月28日

PHP高级开发工程师定制班

PHP高级开发工程师定制班

开班日期:9月28日

 扫一扫,关注一下! 青岛:市南区金坛路17号 济南:历下区趵突泉北路三联商社
济南:历下区山大路47号数码港大厦 潍坊:奎文区东风东街299号建行大厦
烟台:海港路25号阳光100城市广场 临沂:兰山区红旗路1号苏宁易购
淄博:张店区金晶大道68号华润大厦 济宁:市中区太白路10号苏宁生活广场
课程培训电话:15610069419 QQ:2720475033 全国服务监督电话:400-111-8989    服务邮箱 tousu@tedu.cn

2001-2017 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56