PHP之autoload运行机制实例分析


Posted in PHP onAugust 28, 2014

本文较为深入的分析了PHP的autoload运行机制。对于深入理解PHP运行原理有一定的帮助作用。具体分析如下:

php实现autoload有两种方法:

1、拦截器__autoload()

2、设置全局变量函数指针autoload_func为指定函数。通常在c扩展中使用

本质上前者还是通过后者实现的。

分析过程,PHP5.3.6源码:

=>Zend/zend_vm_def.h  1894行
ZEND_VM_HANDLER(109,ZEND_FETCH_CLASS,...
=>zend_execute_API.c 1526行
zend_class_entry *zend_fetch_class(const char *class_name,...
=>zend_execute_API.c 1564行
if(zend_lookup_class_ex(class_name,class_name_len,...
=>zend_execute_API.c 1039行
ZEND_API int zend_lookup_class_ex(const char *na...
=>zend_execute_API.c 1121行
retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC);
=>zend_execute_API.c 758行
       zend_call_function

顾名思义,zend_call_function的主要功能是调用PHP函数。其参数fcall_info, fcall_cache,分别指向两个重要的结构,zend_fcall_info和zend_fcall_info_cache

zend_call_function主要工作流程如下:

如果fcall_cache.function_handler不为NULL,则直接执行 fcall_cache.function_handler指向的函数。
如果 fcall_cache.function_handler为NULL,则尝试查找函数名为fcall_info.function_name的函 数,如果存在的话,则执行之;
 
现总结如下,autoload机制的主要执行过程为:

(1) 检查执行器全局变量函数指针autoload_func是否为NULL。
(2) 如果autoload_func不为NULL,则直接执行autoload_func指针指向的函数用来加载类,并不检查__autoload()函数是否定义。
(3) 如果autoload_func为NULL,则查找系统中是否定义有__autoload()函数。如果没有定义,则报告错误并退出;如果定义了__autoload()函数,则执行__autoload()尝试加载类,并返回加载结果。

自动加载方便了面向对象和代码复用,但是多个类库不同的__autoload又会导致混乱。可以用spl_autoload解决,将不同开发者的拦截器函数都注册到自动加载函数的hashtable中。spl实现自动加载的机制是维护一个hashtable,里面存储有具有自动加载功能的各个函数。

当触发自动加载机制时,zend会在遍历执行这个hashtable里面的函数,直到成功加载类或加载失败后返回。
当需要使用自动加载功能时,使用函数spl_autoload_register()或spl_autoload_register('autoloadfuncitonname')
无参的spl_autoload_register()会默认加载spl_autoload()函数,该函数功能有限,只能在inlcude_path中搜索指定扩展名的类库。

有参的spl_autoload_register()默认不再加载spl_autoload()函数。
可以通过spl_autoload_functions()查看当前自动加载hashtable中的函数,该函数返回一个数组

注意:使用spl_autoload时,系统会忽略拦截器__autoload,除非显式地使用spl_autoload_register('__autoload')将其加入hashtable

希望本文所述对大家的PHP程序设计有所帮助

PHP 相关文章推荐
php获取mysql版本的几种方法小结
Mar 25 PHP
discuz authcode 经典php加密解密函数解析
Jul 12 PHP
PHP 开发环境配置(Zend Server安装)
Apr 28 PHP
LotusPhp笔记之:Cookie组件的使用详解
May 06 PHP
2014年最新推荐的10款 PHP 开发框架
Aug 01 PHP
php实现根据字符串生成对应数组的方法
Sep 22 PHP
php编写的一个E-mail验证类
Mar 25 PHP
php 修改上传文件大小限制实例详解
Oct 23 PHP
thinkphp jquery实现图片上传和预览效果
Jul 22 PHP
PHP中时间加减函数strtotime用法分析
Apr 26 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
PHP7实现和CryptoJS的AES加密方式互通示例【AES-128-ECB加密】
Jun 08 PHP
php+MySQL判断update语句是否执行成功的方法
Aug 28 #PHP
PHP反射机制用法实例
Aug 28 #PHP
PHP对象相互引用的内存溢出实例分析
Aug 28 #PHP
PHP对象递归引用造成内存泄漏分析
Aug 28 #PHP
PHP中cookie和session的区别实例分析
Aug 28 #PHP
PHP实现视频文件上传完整实例
Aug 28 #PHP
PHP获取表单所有复选框的值的方法
Aug 28 #PHP
You might like
实现php加速的eAccelerator dll支持文件打包下载
2007/09/30 PHP
解析centos中Apache、php、mysql 默认安装路径
2013/06/25 PHP
PHP制作3D扇形统计图以及对图片进行缩放操作实例
2014/10/23 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
yii2 在控制器中验证请求参数的使用方法
2019/06/19 PHP
javascript:以前写的xmlhttp池,代码
2008/05/18 Javascript
Javascript 日期处理之时区问题
2009/10/08 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
关于jquery中全局函数each使用介绍
2013/12/10 Javascript
利用javascript数组长度循环数组内所有元素
2013/12/27 Javascript
jQuery学习心得总结(必看篇)
2016/06/10 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
Bootstrap基本样式学习笔记之按钮(4)
2016/12/07 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
详解Node.js中exports和module.exports的区别
2017/04/19 Javascript
详解Node.js串行化流程控制
2017/05/04 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
2018/03/17 Javascript
node基于puppeteer模拟登录抓取页面的实现
2018/05/09 Javascript
Angular4 组件通讯方法大全(推荐)
2018/07/12 Javascript
vue的token刷新处理的方法
2018/07/17 Javascript
react项目实践之webpack-dev-serve
2018/09/14 Javascript
jQuery轻量级表单模型验证插件
2018/10/15 jQuery
[32:36]完美世界DOTA2联赛PWL S3 LBZS vs CPG 第二场 12.12
2020/12/16 DOTA
Python爬虫爬验证码实现功能详解
2016/04/14 Python
教你学会使用Python正则表达式
2017/09/07 Python
python中reader的next用法
2018/07/24 Python
python实现WebSocket服务端过程解析
2019/10/18 Python
python绘制分布折线图的示例
2020/09/24 Python
中国网上药店领导者:1药网
2017/02/16 全球购物
Mio Skincare美国官网:身体紧致及孕期身体护理
2017/03/05 全球购物
益模软件Java笔试题
2012/03/27 面试题
学生打架检讨书1000字
2014/01/16 职场文书
股东协议书范本
2014/04/14 职场文书
公司离职证明标准样本
2014/10/05 职场文书