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中通过Ajax如何实现异步文件上传的代码实例
May 07 PHP
php file_put_contents()功能函数(集成了fopen、fwrite、fclose)
May 24 PHP
深入分析php之面向对象
May 15 PHP
无刷新动态加载数据 滚动条加载适合评论等页面
Oct 16 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(三)
Jun 23 PHP
Yii框架上传图片用法总结
Mar 28 PHP
Zend Framework前端控制器用法示例
Dec 11 PHP
php实现多维数组排序的方法示例
Mar 23 PHP
Laravel框架实现的使用smtp发送邮件功能示例
Mar 12 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
Feb 21 PHP
PHP7移除的扩展和SAPI
Mar 09 PHP
thinkphp5 路由分发原理
Mar 18 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服务器实现多session并发运行
2006/10/09 PHP
PHP生成月历代码
2007/06/14 PHP
php程序之die调试法 快速解决错误
2009/09/17 PHP
PHP封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
2014/06/19 PHP
php中header设置常见文件类型的content-type
2015/06/23 PHP
PHP保存session到memcache服务器的方法
2016/01/19 PHP
YII框架批量插入数据的方法
2017/03/18 PHP
Laravel框架实现的使用smtp发送邮件功能示例
2019/03/12 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
javascript iframe内的函数调用实现方法
2009/07/19 Javascript
js获取本机的外网/广域网ip地址完整源码
2013/08/12 Javascript
JQuery中使文本框获得焦点的方法实例分析
2015/02/28 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
原生态js,鼠标按下后,经过了那些单元格的简单实例
2016/08/11 Javascript
BootStrap无限级分类(无限极分类封装版)
2016/08/26 Javascript
详解Vue生命周期的示例
2017/03/10 Javascript
基于JavaScript实现数码时钟效果
2020/03/30 Javascript
深入浅出webpack教程系列_安装与基本打包用法和命令参数详解
2017/09/10 Javascript
利用Javascript实现一套自定义事件机制
2017/12/14 Javascript
Vue实现带进度条的文件拖动上传功能
2018/02/23 Javascript
vue.js 实现点击展开收起动画效果
2018/07/07 Javascript
详解js静态检查工具eslint配置文件
2018/11/23 Javascript
使用vuepress搭建静态博客的示例代码
2019/02/14 Javascript
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
微信小程序实现购物车代码实例详解
2019/08/29 Javascript
解决layer弹出层自适应页面大小的问题
2019/09/16 Javascript
Django REST为文件属性输出完整URL的方法
2017/12/18 Python
Python  word实现读取及导出代码解析
2020/07/09 Python
写给女朋友的道歉信
2014/01/08 职场文书
森林防火工作方案
2014/02/14 职场文书
医院学雷锋活动策划方案
2014/02/15 职场文书
《商鞅南门立木》教学反思
2014/02/16 职场文书
餐饮投资计划书
2014/04/25 职场文书
单位委托函范文
2015/01/29 职场文书
2015仓库保管员年终工作总结
2015/05/13 职场文书
在项目中使用redis做缓存的一些思路
2021/09/14 Redis