PHP之autoload运行机制实例分析_php技巧

本文较为深入的分析了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程序设计有所帮助

时间: 2024-10-29 02:01:47

PHP之autoload运行机制实例分析_php技巧的相关文章

PHP实现事件机制实例分析_php技巧

本文实例讲述了PHP实现事件机制的方法.分享给大家供大家参考.具体分析如下: 内置了事件机制的语言不多,php也没有提供这样的功能.事件(Event)说简单了就是一个Observer模式,实现起来很容易.但是有所不同的是,事件的监听者谁都可以加,但是只能由直接包含它的对象触发.这就有一点点难度了.php有一个debug_backtrace函数,可以得到当前的调用栈,由此可以找到判断调用事件触发函数的对象是不是直接包含它的对象的办法. <?php /** * 事件 * * @author xiez

基于PHP实现的事件机制实例分析_php技巧

本文实例讲述了基于PHP实现的事件机制.分享给大家供大家参考.具体分析如下: 内置了事件机制的语言不多,php也没有提供这样的功能.事件(Event)说简单了就是一个Observer模式,实现起来很容易.但是有所不同的是,事件的监听者谁都可以加,但是只能由直接包含它的对象触发.这就有一点点难度了.php有一个debug_backtrace函数,可以得到当前的调用栈,由此可以找到判断调用事件触发函数的对象是不是直接包含它的对象的办法. <?php /** * 事件 * * @author xiez

PHP多线程之内部多线程实例分析_php技巧

本文实例分析了PHP多线程之内部多线程用法.分享给大家供大家参考.具体如下: 复制代码 代码如下: <?php class Http_MultiRequest {     //要并行抓取的url 列表     private $urls = array();     //curl 的选项     private $options;     //构造函数     function __construct($options = array())     {         $this->setOp

php中strlen和mb_strlen用法实例分析_php技巧

本文实例分析了php中strlen和mb_strlen用法.分享给大家供大家参考,具体如下: 首先看如下代码(文件编码utf8): <?php $utf8_string = "abcd我你他她它"; var_dump(strlen($utf8_string)); var_dump(mb_strlen($utf8_string, 'gb2312')); var_dump(mb_strlen($utf8_string, 'utf8')); var_dump(mb_strlen($ut

PHP中STDCLASS用法实例分析_php技巧

本文实例讲述了PHP中STDCLASS用法.分享给大家供大家参考,具体如下: PHP中STDCLASS在我们开发应用中使用到的不多,但是PHP中STDCLASS作用是非常的大的,下面我们一起来看PHP中STDCLASS的用法. 在WordPress中很多地方使用stdClass来定义一个对象(而通常是用数组的方式),然后使用get_object_vars来把定义的对象『转换』成数组. 如下代码所示: $tanteng = new stdClass(); $tanteng->name = 'tan

C#静态方法与非静态方法实例分析_php技巧

本文实例分析了C#静态方法与非静态方法,并对其用法进行了较为全面的分析.分享给大家供大家参考.具体分析如下: 通常来说,C#的类中可以包含两种方法:静态方法和非静态方法. 使用了static 修饰符的方法为静态方法,反之则是非静态方法. 静态方法是一种特殊的成员方法,它不属于类的某一个具体的实例,而是属于类本身.所以对静态方法不需要首先创建一个类的实例,而是采用 类名.静态方法 的格式 . 1)static方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用. static内部

PHP数组函数array_multisort()用法实例分析_php技巧

本文实例分析了PHP数组函数array_multisort()用法.分享给大家供大家参考,具体如下: 有时候我们需要对二维数组的某个键的值进行排序,这里就是讨论这个问题.我们可以使用array_multisort()这个函数.array_multisort() 函数对多个数组或多维数组进行排序. 参数中的数组被当成一个表的列并以行来进行排序 - 这类似 SQL 的 ORDER BY 子句的功能.第一个数组是要排序的主要数组.数组中的行(值)比较为相同的话,就会按照下一个输入数组中相应值的大小进行

php表单提交与$_POST实例分析_php技巧

本文实例分析了php的表单提交与$_POST.分享给大家供大家参考.具体如下: 这里要注意:表单 checkbox 的 name 需要以数组形式来命名. 表单文件:index.php 复制代码 代码如下: <form action="b.php" method="post"> 用户名:<input type="text" name="username"><br /> 密码:<input

php自动载入类用法实例分析_php技巧

本文实例讲述了php自动载入类用法.分享给大家供大家参考,具体如下: <?php //function __autoload($class_name) { // require_once $class_name . '.php'; //} spl_autoload_register(array("core",'autoload'));//当实例化类的时候,自动调用core类中的autoload()方法来载入类 //也可以使用__autoload()来实现,但是php新版本建议使用