原:PHP内核函数研究之 global

news/2024/12/25 15:12:50 标签: php, zend, table, string, list, null
声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。
欢迎转载,转载请注明出处 。

本文地址:http://imsiren.com/archives/601


好久没有写博客了…最近事挺多,
换了工作,又搬了家..
今天就来说说 我们经常用到的global语句吧..
我们都知道,在函数体内声明的变量,作用域只是当前函数体中,一般情况下是访问不到外部声明的变量的.
因为全局变量和局部变量存放在不同的hashTable,
全局变量在symbol_table中,而局部变量则存在active_symbol_table中.
这样就将它们分开了,那 global是怎么实现的呢?
经过简单分析,通过RE2C&&YACC定位到 global的token

T_GLOBAL global_var_list ';'
................
global_var_list:
                global_var_list ',' global_var  { zend_do_fetch_global_variable(&$3, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); }
        |       global_var                                              { zend_do_fetch_global_variable(&$1, NULL, ZEND_FETCH_GLOBAL_LOCK TSRMLS_CC); }
;

重点是在zend_do_fetch_global_variable这个函数中,我们进去看看,

void zend_do_fetch_global_variable(znode * varname,const znode * static_assignment,int
    fetch_type TSRMLS_DC) /* {{{ */ {
    zend_op * opline;
    znode lval;
    znode result;
    if(varname->op_type == IS_CONST) {
        if(Z_TYPE(varname->u . constant) != IS_STRING) {
            convert_to_string(&varname->u . constant);
        }
    }
    opline = get_next_op(CG(active_op_array)TSRMLS_CC);
    opline->opcode = ZEND_FETCH_W;
     /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
    opline->result . op_type = IS_VAR;
    opline->result . u . EA . type = 0;
    opline->result . u . var = get_temporary_variable(CG(active_op_array));
    opline->op1 = * varname;
    SET_UNUSED(opline->op2);
    opline->op2 . u . EA . type = fetch_type;
    result = opline->result;
    if(varname->op_type == IS_CONST) {
        zval_copy_ctor(&varname->u . constant);
    }
    fetch_simple_variable(&lval,varname,0TSRMLS_CC);
     /* Relies on the fact that the default fetch is BP_VAR_W */
    zend_do_assign_ref(NULL,&lval,&result TSRMLS_CC);
    CG(active_op_array)->opcodes[CG(active_op_array)->last - 1] . result . u . EA . type |=
        EXT_TYPE_UNUSED;
}

1:此函数先验证我们获取的变量是否是常量,如果是常量并且不是字符串类型,则就将它转换成string类型.
2:此函数生成一个Op , ZEND_FETCH_W
3:释放CONST
4:fetch_simple_variable会检测是不是auto_global
最重要的地方是 ZEND_FETCH_W
通过计算 可以知道 op的函数是ZEND_FETCH_W_SPEC_CV_HANDLER


static int ZEND_FASTCALL  ZEND_FETCH_W_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
        return zend_fetch_var_address_helper_SPEC_CV(BP_VAR_W, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}

zend_fetch_var_address_helper_SPEC_CV的工作:
1:转换成IS_STRING类型
2:如果是类的静态成员,则通过::获取过来,否则,通过zend_get_target_symbol_table函数返回全局变量symbol_table .
return &EG(symbol_table);
3:通过zend_hash_find 在 target_symbol_table 中查找,target_symbol_table是一个临时HashTable.用来存放 symbol_table的数据.
4: 如果没有找到,则会以写的方式 创建一条数据到target_symbol_table中.这就是,我们为什么通过global一个不存在的变量的时候不出错,并且会创建该变量的原因.

原文出处: http://imsiren.com/archives/601


http://www.niftyadmin.cn/n/1790439.html

相关文章

win10安装3DSMAX失败,怎么强力卸载删除注册表并重新安装

一些搞设计的朋友在win10系统下安装3DSMAX失败或提示已安装,也有时候想重新安装3DSMAX的时候会出现本电脑windows系统已安装3DSMAX,你要是不留意直接安装3DSMAX,只会安装3DSMAX的附件或者直接提示失败,3DSMAX是不会安装上的。这种…

实现简单的ssh功能

客户端代码: # -*- codingutf-8 -*-__Author__ "Dennis"import socketclient socket.socket()client.connect(("localhost",6969))while True: msg input(">> ") if not msg:continue client.send(msg.encode()) …

PHP内核函数研究之error_log

声明:本文为 斯人原创,全部为作者一一分析得之,有不对的地方望赐教。 欢迎转载,转载请注明出处 。 本文地址: http://imsiren.com/archives/617PHP有一个很强大的日志处理函数:error_log,我们可以用它来记录我们程序中…

云计算的PaaS是什么?

在当今科技飞速发展的时代,每天都有无数的科技术语在我们耳边飘扬。云计算就是其中之一。我们知道云计算有很多种服务,那么什么是PaaS?云容科技小编向您介绍。 首先,我们需要知道paas是平台服务的缩写,也就是云计算运营…

启动及更改tomcat 配置

到tomcat安装的bin目录下面,双击那个startup.bat文件,启动Tomcat 去浏览器输入 http://localhost:8080/ 然后出现下面的界面,那就说明你的tomcat配置成功了 端口更改 - conf ->server.xml (jenkins 端口默认也是8080,为了避免冲突&#x…

【ubuntu】ubuntu 常用设置及软件安装

目录 一、更新aliyun源二、安装chrome三、创建idea桌面快捷方式四、挂载exfat五、桌面版安装网易云音乐六、给firefox 安装flash七、firefox 取消确认关闭多标签八、Ubuntu 16上安装Code::Blocks九、防火墙设置十、vm tool 安装十一、安装maven一、更新aliyun源 #备份 $ sudo c…

如何在扩展里调用PHP函数呢?

声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。 欢迎转载,转载请注明出处 。 本文地址: http://imsiren.com/archives/606在写扩展的时候,肯定不能什么功能都自己实现,原因有…

从 SPA 到 PWA:Web App的下一站在哪?

从AJAX(Asynchronous JavaScript XML,异步JavaScript和XML)开始, 尤其是 AngularJS 推出之后,SPA(Single Page App,单页应用)已经成为前端 App 的必选方案。 SPA 可以在客户端提供完…