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开发留言板的CRUD(增,删,改,查)操作
Apr 19 PHP
php 函数中使用static的说明
Jun 01 PHP
mysql,mysqli,PDO的各自不同介绍
Sep 19 PHP
windows下zendframework项目环境搭建(通过命令行配置)
Dec 06 PHP
详解PHP中strlen和mb_strlen函数的区别
Mar 07 PHP
php+mysql实现简单的增删改查功能
Jul 13 PHP
详解PHP的Yii框架中日志的相关配置及使用
Dec 08 PHP
PHP中ID设置自增后不连续的原因分析及解决办法
Aug 21 PHP
PHP 输出缓冲控制(Output Control)详解
Aug 25 PHP
替换php字符串中的单引号为双引号的方法
Feb 16 PHP
PHP读取目录树的实现方法分析
Mar 22 PHP
laravel框架分组控制器和分组路由实现方法示例
Jan 25 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使用Cookie控制访问授权的方法
2015/01/21 PHP
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
5个书写JavaScript代码的坏习惯,看看你中枪了没?
2014/11/06 Javascript
JavaScript数组合并的多种方法
2016/05/22 Javascript
只要1K 纯JS脚本送你一朵3D红色玫瑰
2016/08/09 Javascript
node.js版本管理工具n无效的原理和解决方法
2016/11/24 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
2017/07/27 Javascript
Echarts基本用法_动力节点Java学院整理
2017/08/11 Javascript
angularjs利用directive实现移动端自定义软键盘的示例
2017/09/20 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
实例详解ztree在vue项目中使用并且带有搜索功能
2018/08/24 Javascript
你所不知道的Python奇技淫巧13招【实用】
2016/12/14 Python
python使用matplotlib画饼状图
2018/09/25 Python
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
Python操作json的方法实例分析
2018/12/06 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
Python基于字典实现switch case函数调用
2020/07/22 Python
Python利用Faiss库实现ANN近邻搜索的方法详解
2020/08/03 Python
python中Django文件上传方法详解
2020/08/05 Python
Python基础进阶之海量表情包多线程爬虫功能的实现
2020/12/17 Python
CSS3制作彩色进度条样式的代码示例分享
2016/06/23 HTML / CSS
Booking.com美国:全球酒店预订网站
2017/04/18 全球购物
法国包包和行李箱销售网站:Bagage24.fr
2020/03/24 全球购物
土木工程个人自荐信范文
2013/11/30 职场文书
《美丽的小路》教学反思
2014/02/26 职场文书
应届大专毕业生自我鉴定
2014/04/08 职场文书
服务承诺书怎么写
2014/05/24 职场文书
入党宣誓仪式主持词
2015/06/29 职场文书
大学同学聚会感言
2015/07/30 职场文书
职场中的你,辞职信写对了吗?
2019/06/26 职场文书
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
go:垃圾回收GC触发条件详解
2021/04/24 Golang
Go语言读取txt文档的操作方法
2022/01/22 Golang