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 相关文章推荐
BBS(php &amp; mysql)完整版(一)
Oct 09 PHP
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
Jun 08 PHP
从Web查询数据库之PHP与MySQL篇
Sep 25 PHP
php设计模式 FlyWeight (享元模式)
Jun 26 PHP
10个实用的PHP代码片段
Sep 02 PHP
第三章 php操作符与控制结构代码
Dec 30 PHP
带密匙的php加密解密示例分享
Jan 29 PHP
php实现将任意进制数转换成10进制的方法
Apr 17 PHP
php函数重载的替代方法--伪重载详解
May 08 PHP
yii使用activeFileField控件实现上传文件与图片的方法
Dec 28 PHP
thinkPHP中volist标签用法示例
Dec 06 PHP
ThinkPHP 3.2.2实现事务操作的方法
May 05 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
PHP合并数组+号和array_merge的区别
2015/06/25 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
PHP实现微信退款功能
2018/10/02 PHP
PHP微商城开源代码实例
2019/03/27 PHP
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
javascript实现的网页局布刷新效果
2008/12/01 Javascript
Jqyery中同等与js中windows.onload的应用
2011/05/10 Javascript
javascript中打印当前的时间实现思路及代码
2013/12/18 Javascript
了解Javascript的模块化开发
2015/03/02 Javascript
jquery弹出遮掩层效果【附实例代码】
2016/04/28 Javascript
JS+HTML5手机开发之滚动和惯性缓动实现方法分析
2016/06/12 Javascript
JS实现的多张图片轮流播放幻灯片效果
2016/07/22 Javascript
深入浅析JavaScript中的3DES
2016/08/24 Javascript
预防网页挂马的方法总结
2016/11/03 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
vue+iview+less+echarts实战项目总结
2018/02/22 Javascript
jQuery实现图片简单轮播功能示例
2018/08/13 jQuery
layer.prompt使文本框为空的情况下也能点击确定的方法
2019/09/24 Javascript
jQuery cookie的公共方法封装和使用示例
2020/06/01 jQuery
vue中组件通信详解(父子组件, 爷孙组件, 兄弟组件)
2020/07/27 Javascript
vue添加自定义右键菜单的完整实例
2020/12/08 Vue.js
[05:41]2014DOTA2西雅图国际邀请赛 小组赛7月10日TOPPLAY
2014/07/10 DOTA
Python程序员开发中常犯的10个错误
2014/07/07 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
HTML5是否真的可以取代Flash
2010/02/10 HTML / CSS
荷兰和比利时时尚鞋店:Van Dalen
2018/04/23 全球购物
Bibloo奥地利:购买女装、男装、童装、鞋和配件
2018/10/18 全球购物
政治思想表现评语
2014/05/04 职场文书
阅兵口号
2014/06/19 职场文书
2014教育局对照检查材料思想汇报
2014/09/23 职场文书
优秀党务工作者先进事迹材料
2014/12/25 职场文书
护士节慰问信
2015/02/15 职场文书
2016年共产党员个人承诺书
2016/03/24 职场文书
Go语言操作数据库及其常规操作的示例代码
2021/04/21 Golang
MongoDB数据库部署环境准备及使用介绍
2022/03/21 MongoDB