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中如何定义和使用常量
Feb 28 PHP
php Hex RGB颜色值互换的使用
May 10 PHP
php-cli简介(不会Shell语言一样用Shell)
Jun 03 PHP
php防注入,表单提交值转义的实现详解
Jun 10 PHP
PHP中SimpleXML函数用法分析
Nov 26 PHP
PHP获取指定时间段之间的 年,月,天,时,分,秒
Jun 05 PHP
PHP简单日历实现方法
Jul 20 PHP
PHP面向对象自动加载机制原理与用法分析
Oct 14 PHP
PHP 7安装调试工具Xdebug扩展的方法教程
Jun 17 PHP
Laravel构建即时应用的一种实现方法详解
Aug 31 PHP
PHP里的$_GET数组介绍
Mar 22 PHP
Yii框架常见缓存应用实例小结
Sep 09 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
留言板翻页的实现详解
2006/10/09 PHP
php中static静态变量的使用方法详解
2010/06/04 PHP
一个简单且很好用的php分页类
2013/10/26 PHP
PHP 登录完成后如何跳转上一访问页面
2014/01/14 PHP
thinkphp循环结构用法实例
2014/11/24 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
2019/11/25 PHP
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
vue 页面加载进度条组件实例
2018/02/05 Javascript
jQuery中将json数据显示到页面表格的方法
2018/05/27 jQuery
vue中使用heatmapjs的示例代码(结合百度地图)
2018/09/05 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
nuxt静态部署打包相对路径操作
2020/11/06 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
python读写文件操作示例程序
2013/12/02 Python
跟老齐学Python之再深点,更懂list
2014/09/20 Python
Python实现的简单算术游戏实例
2015/05/26 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
Python函数装饰器实现方法详解
2018/12/22 Python
python爬取微信公众号文章的方法
2019/02/26 Python
详解python中的hashlib模块的使用
2019/04/22 Python
pandas 空数据处理方法详解
2019/11/02 Python
Python命令行click参数用法解析
2019/12/19 Python
python 基于Apscheduler实现定时任务
2020/12/15 Python
新郎父亲婚宴答谢词
2014/01/11 职场文书
2014年设计师工作总结
2014/11/25 职场文书
民主生活会汇报材料
2014/12/15 职场文书
营销计划书范文
2015/01/17 职场文书
八年级上册语文教学计划
2015/01/22 职场文书
医生个人年度总结
2015/02/28 职场文书
2015年反腐倡廉工作总结
2015/05/14 职场文书
赢在执行观后感
2015/06/16 职场文书
统招统分证明
2015/06/23 职场文书
嘉年华活动新闻稿
2015/07/17 职场文书