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 获取远程网页内容的函数
Sep 08 PHP
PHP为表单获取的URL 地址预设 http 字符串函数代码
May 26 PHP
php下清空字符串中的HTML标签的代码
Sep 06 PHP
php 中的4种标记风格介绍
May 10 PHP
PHP加密扩展库Mcrypt安装和实例
Nov 10 PHP
Ajax和PHP正则表达式验证表单及验证码
Sep 24 PHP
Yii2第三方类库插件Imagine的安装和使用
Jul 06 PHP
Yii 2中的load()和save()示例详解
Aug 03 PHP
深入理解PHP中mt_rand()随机数的安全
Oct 12 PHP
PHP性能测试工具xhprof安装与使用方法详解
Apr 29 PHP
Smarty模板变量与调节器实例详解
Jul 20 PHP
php简单检测404页面的方法示例
Aug 23 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
Apache2 httpd.conf 中文版
2006/11/17 PHP
PHP+FLASH实现上传文件进度条相关文件 下载
2007/07/21 PHP
php PDO中文乱码解决办法
2009/07/20 PHP
php中使用sftp教程
2015/03/30 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
CI框架AR操作(数组形式)实现插入多条sql数据的方法
2016/05/18 PHP
PHP时间戳格式全部汇总 (获取时间、时间戳)
2016/06/13 PHP
PHP回调函数与匿名函数实例详解
2017/08/16 PHP
详解php与ethereum客户端交互
2018/04/28 PHP
php微信开发之关注事件
2018/06/14 PHP
解决PHP curl或file_get_contents下载图片损坏或无法打开的问题
2019/10/11 PHP
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
JavaScript 原型继承
2011/12/26 Javascript
html+javascript实现可拖动可提交的弹出层对话框效果
2013/08/05 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
Javascript基础教程之if条件语句
2015/01/18 Javascript
jQuery Timelinr实现垂直水平时间轴插件(附源码下载)
2016/02/16 Javascript
基于jQuery实现收缩展开功能
2016/03/18 Javascript
Seajs是什么及sea.js 由来,特点以及优势
2016/10/13 Javascript
Bootstrap CSS组件之下拉菜单(dropdown)
2016/12/17 Javascript
原生ajax处理json格式数据的实例代码
2016/12/25 Javascript
详解基于node.js的脚手架工具开发经历
2019/01/28 Javascript
使用Vue-Awesome-Swiper实现旋转叠加轮播效果&amp;平移轮播效果
2019/08/16 Javascript
浅析Python中将单词首字母大写的capitalize()方法
2015/05/18 Python
python 截取 取出一部分的字符串方法
2017/03/01 Python
Python实现的简单计算器功能详解
2018/08/25 Python
Python封装原理与实现方法详解
2018/08/28 Python
Python第三方Window模块文件的几种安装方法
2018/11/22 Python
Python语言异常处理测试过程解析
2020/01/08 Python
卡骆驰德国官方网站:Crocs德国
2019/03/29 全球购物
Java面试中常遇到的问题,也是需要注意的几点
2013/08/30 面试题
采购部部长岗位职责
2014/02/06 职场文书
化工操作工岗位职责
2014/04/29 职场文书
环保倡议书格式范文
2014/05/14 职场文书
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
HTML页面中使两个div并排显示的实现
2022/05/15 HTML / CSS