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模拟SQL Server的两个日期处理函数
Oct 09 PHP
PHP 中的批处理的实现
Jun 14 PHP
PHP 解决utf-8和gb2312编码转换问题
Mar 18 PHP
基于PHP开发中的安全防范知识详解
Jun 06 PHP
PHP自定义大小验证码的方法详解
Jun 07 PHP
php中字符查找函数strpos、strrchr与strpbrk用法
Nov 18 PHP
PHP分页类集锦
Nov 18 PHP
php可生成缩略图的文件上传类实例
Dec 17 PHP
PHP实现的带超时功能get_headers函数
Feb 10 PHP
浅谈COOKIE和SESSION区别
Jul 19 PHP
WordPress主题制作之模板文件的引入方法
Dec 28 PHP
Yii框架getter与setter方法功能与用法分析
Oct 22 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中文分词的简单实现代码分享
2011/07/17 PHP
php数组添加元素方法小结
2014/12/20 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
java微信开发之上传下载多媒体文件
2016/06/24 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
PHP中md5()函数的用法讲解
2019/03/30 PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
2019/06/19 PHP
laravel 实现设置时区的简单方法
2019/10/10 PHP
PHP扩展类型及安装方式解析
2020/04/27 PHP
脚本吧 - 幻宇工作室用到js,超强推荐base.js
2006/12/23 Javascript
用JavaScript页面不刷新时全选择,全删除(GridView)
2009/04/14 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
JS中的forEach、$.each、map方法推荐
2016/04/05 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
JQ选择器_选择同类元素的第N个子元素的实现方法
2016/09/08 Javascript
nodejs的HTML分析利器node-jquery用法浅析
2016/11/08 NodeJs
详解能在多种前端框架下使用的表格控件
2017/01/11 Javascript
TypeScript中的方法重载详解
2019/04/12 Javascript
Vue+Java+Base64实现条码解析的示例
2020/09/23 Javascript
[01:24:51]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第二场
2014/05/26 DOTA
[01:55]《走出家门看比赛》——DOTA2 2015国际邀请赛同城线下观战
2015/07/18 DOTA
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
pandas 对每一列数据进行标准化的方法
2018/06/09 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
澳大利亚在线高跟鞋商店:Shoe Me
2019/11/19 全球购物
沃尔玛加拿大:Walmart.ca
2020/03/02 全球购物
公司门卫岗位职责
2014/03/15 职场文书
篮球比赛口号
2014/06/10 职场文书
2014年学校国庆主题活动方案
2014/09/16 职场文书
结婚十年感言
2015/07/31 职场文书
你为什么是穷人?可能是这5个缺点造成
2019/07/11 职场文书
vue中this.$http.post()跨域和请求参数丢失的解决
2022/04/08 Vue.js