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 相关文章推荐
php下过滤HTML代码的函数
Dec 10 PHP
PHP 解决session死锁的方法
Jun 20 PHP
thinkphp验证码显示不出来的解决方法
Mar 29 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
Jul 28 PHP
PHP设计模式之简单投诉页面实例
Feb 24 PHP
Yii2主题(Theme)用法详解
Jul 23 PHP
PHP中in_array函数使用的问题与解决办法
Sep 11 PHP
php实现保存周期为1天的购物车类
Jul 07 PHP
PC端微信扫码支付成功之后自动跳转php版代码
Jul 07 PHP
PHP编程中的Session阻塞问题与解决方法分析
Aug 07 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
Sep 17 PHP
PHP实现的DES加密解密类定义与用法示例
Nov 02 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
德劲1103的维修打理经验
2021/03/02 无线电
PHP设计模式之观察者模式(Observer)详细介绍和代码实例
2014/04/08 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
php socket客户端及服务器端应用实例
2014/07/04 PHP
thinkPHP学习笔记之安装配置篇
2015/03/05 PHP
PHP获取网站中各文章的第一张图片的代码示例
2016/05/20 PHP
Javascript 刷新全集常用代码
2009/11/22 Javascript
JavaScript 事件系统
2010/07/22 Javascript
javascript中Array数组的迭代方法实例分析
2015/02/04 Javascript
JS检测页面中哪个HTML标签触发点击事件的方法
2016/06/17 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
使用HTML5+Boostrap打造简单的音乐播放器
2016/08/05 Javascript
Angularjs 设置全局变量的方法总结
2016/10/20 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
2016/10/21 Javascript
JavaScript中的遍历详解(多种遍历)
2017/04/07 Javascript
jQuery实现右侧抽屉式在线客服功能
2017/12/25 jQuery
详解Vue组件之间通信的七种方式
2019/04/14 Javascript
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
2019/05/22 Javascript
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
[01:20]PWL开团时刻DAY9——听说潮汐没用?
2020/11/10 DOTA
Python写的贪吃蛇游戏例子
2014/06/16 Python
Pycharm技巧之代码跳转该如何回退
2017/07/16 Python
Python数据拟合与广义线性回归算法学习
2017/12/22 Python
python字典的常用方法总结
2019/07/31 Python
Pandas之read_csv()读取文件跳过报错行的解决
2020/04/21 Python
CSS3 实现的火焰动画
2020/12/07 HTML / CSS
html5 figure和figcaption的使用方法
2018/09/10 HTML / CSS
加拿大女鞋品牌:ALDO
2016/11/13 全球购物
法国购买隐形眼镜和眼镜网站:Optical Center
2019/10/08 全球购物
构造器Constructor是否可被override?
2013/08/06 面试题
体育专业个人的求职信范文
2013/09/21 职场文书
2014镇党委班子对照检查材料思想汇报
2014/09/23 职场文书
2015年试用期工作总结
2014/12/12 职场文书
Python如何配置环境变量详解
2021/05/18 Python
Netty分布式客户端接入流程初始化源码分析
2022/03/25 Java/Android