php中spl_autoload详解


Posted in PHP onOctober 17, 2014

SPL有两个不同的函数 spl_autoload, spl_autoload_call,通过将autoload_func指向这两个不同的函数地址来实现不同的自动加载机制。

spl_autoload 是SPL实现的默认的自动加载函数,它的功能比较简单。它可以接收两个参数,第一个参数是$class_name,表示类名,第二个参 数$file_extensions是可选的,表示类文件的扩展名" title="扩展名">扩展名,可以在$file_extensions中指定多个扩展名" title="扩展名">扩展名,护展名之间用分号隔开即 可;如果不指定的话,它将使用默认的扩展名" title="扩展名">扩展名.inc或.php。spl_autoload首先将$class_name变为小写,然后在所有的 include path中搜索$class_name.inc或$class_name.php文件(如果不指定$file_extensions参数的话),如果找 到,就加载该类文件。你可以手动使用spl_autoload(”Person”, “.class.php”)来加载Person类。实际上,它跟require/include差不多,不同的它可以指定多个扩展名" title="扩展名">扩展名。

怎 样让spl_autoload自动起作用呢,也就是将autoload_func指向spl_autoload?答案是使用 spl_autoload_register函数。在PHP脚本中第一次调用spl_autoload_register()时不使用任何参数,就可以将 autoload_func指向spl_autoload。

通过上面的说明我们知道,spl_autoload的功能比较简单,而且它是在SPL扩展中实现的,我们无法扩充它的功能。如果想实现自己的更灵活的自动加载机制怎么办呢?这时,spl_autoload_call函数闪亮登场了。

我 们先看一下spl_autoload_call的实现有何奇妙之处。在SPL模块内部,有一个全局变量autoload_functions,它本质上是 一个HashTable,不过我们可以将其简单的看作一个链表,链表中的每一个元素都是一个函数指针,指向一个具有自动加载类功能的函数。 spl_autoload_call本身的实现很简单,只是简单的按顺序执行这个链表中每个函数,在每个函数执行完成后都判断一次需要的类是否已经加载, 如果加载成功就直接返回,不再继续执行链表中的其它函数。如果这个链表中所有的函数都执行完成后类还没有加载,spl_autoload_call就直接 退出,并不向用户报告错误。因此,使用了autoload机制,并不能保证类就一定能正确的自动加载,关键还是要看你的自动加载函数如何实现。

在php5中的标准库方法spl_autoload相当于实现自己的__autoload

<?php

    function __autoload($classname){

        if(is_file($classname.'.php'){

            include $classname.'.php';

        } elseif(is_file($classname.'.inc'){

            include $classname.'.inc';

        }

    }

它会在注册目录下自动寻找与$classname同名的.php/.inc文件。当然,你也可以指定特定类型的文件,方法是注册扩展名

<?php

    spl_autoload_extensions('.php,.inc,.some');

这样,它也会搜索.some文件。默认,php是不会启动spl_autoload的,那么怎样才能自动让spl_autoload生效呢呢?方法是

<?php

    spl_autoload_register();

spl_autoload_register有一个$callback参数,如果不指定,它就会自动注册spl_autoload,为了能搜寻更多的自动加载目录,可以在这些代码前面设置自动加载目录

<?php

    set_include_path(get_include_path() . PATH_SEPARATOR . 'some/path' . DIRECTORY_SEPARATOR);

这样,当php找不到指定的类时,就会在set_include_path指定的目录下寻找。

这些方法常用在php框架中。比如把上面的介绍串连起来:

<?php

set_include_path(get_include_path() . PATH_SEPARATOR . 'some/path' . DIRECTORY_SEPARATOR);

spl_autoload_extensions('.php,.inc,.some');

spl_autoload_register();

当你要加载some/path下面的classA类时,它会在目录下寻找classa.php或classa.inc或classa.some,这样你就可以放心地运用new classA或extends classA

<?php

    ClassB extends ClassA {

        // code..

    }
    $a = new ClassA;

    $b = new ClassB;
PHP 相关文章推荐
第十二节--类的自动加载
Nov 16 PHP
按上下级层次关系输出内容的PHP代码
Jul 17 PHP
使用NetBeans + Xdebug调试PHP程序的方法
Apr 12 PHP
解析thinkphp中的导入文件标签
Jun 20 PHP
PHP 关于访问控制的和运算符优先级介绍
Jul 08 PHP
php实现读取和写入tab分割的文件
Jun 01 PHP
PHP基于单例模式实现的mysql类
Jan 09 PHP
php5.2的curl-bug 服务器被php进程卡死问题排查
Sep 19 PHP
基于php流程控制语句和循环控制语句(讲解)
Oct 23 PHP
PHP7中I/O模型内核剖析详解
Apr 14 PHP
Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
Dec 04 PHP
PHP遍历数组的6种方式总结
Nov 17 PHP
php中__destruct与register_shutdown_function执行的先后顺序问题
Oct 17 #PHP
PHP图片自动裁切应付不同尺寸的显示
Oct 16 #PHP
PHP 抽象方法与抽象类abstract关键字介绍及应用
Oct 16 #PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
Oct 16 #PHP
php实现扫描二维码根据浏览器类型访问不同下载地址
Oct 15 #PHP
ThinkPHP基于PHPExcel导入Excel文件的方法
Oct 15 #PHP
ThinkPHP分页实例
Oct 15 #PHP
You might like
PHP4实际应用经验篇(6)
2006/10/09 PHP
对squid中refresh_pattern的一些理解和建议
2009/04/17 PHP
用穿越火线快速入门php面向对象
2012/02/22 PHP
php带抄送和密件抄送的邮件发送方法
2015/03/20 PHP
php获取错误信息的方法
2015/07/17 PHP
php实现异步数据调用的方法
2015/12/24 PHP
phpcms配置列表页以及获得文章发布时间
2017/07/04 PHP
PHP微信公众号开发之微信红包实现方法分析
2017/07/14 PHP
laravel5.6 框架操作数据 Eloquent ORM用法示例
2020/01/26 PHP
Jquery iframe内部出滚动条
2010/02/11 Javascript
JQuery datepicker 使用方法
2011/05/20 Javascript
网页右侧悬浮滚动在线qq客服代码示例
2014/04/28 Javascript
js获取窗口相对于屏幕左边和上边的位置坐标
2014/05/15 Javascript
前端学习笔记style,currentStyle,getComputedStyle的用法与区别
2016/05/28 Javascript
修改Nodejs内置的npm默认配置路径方法
2018/05/13 NodeJs
JavaScript中EventBus实现对象之间通信
2020/10/18 Javascript
JavaScript实现瀑布流布局的3种方式
2020/12/27 Javascript
python应用程序在windows下不出现cmd窗口的办法
2014/05/29 Python
python 把数据 json格式输出的实例代码
2016/10/31 Python
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
2018/02/13 Python
Django模板导入母版继承和自定义返回Html片段过程解析
2019/09/18 Python
Python 类属性与实例属性,类对象与实例对象用法分析
2019/09/20 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
Python如何定义接口和抽象类
2020/07/28 Python
Pycharm2020最新激活码|永久激活(附最新激活码和插件的详细教程)
2020/09/29 Python
英国景点门票网站:attractiontix
2019/08/27 全球购物
公司周年庆典邀请函
2014/01/12 职场文书
师德个人剖析材料
2014/02/02 职场文书
企业安全生产承诺书
2014/05/22 职场文书
公司试用期员工自我评价
2014/09/17 职场文书
药店营业员岗位职责
2015/04/14 职场文书
安全知识竞赛主持词
2015/06/30 职场文书
应收账款管理制度
2015/08/06 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
总结高并发下Nginx性能如何优化
2021/11/01 Servers
NASA 机智号火星直升机拍到了毅力号设备碎片
2022/04/29 数码科技