设为首页 收藏本站
查看: 421|回复: 0

[经验分享] 原创:PHP内核研究 静态变量

[复制链接]

尚未签到

发表于 2017-4-2 10:35:00 | 显示全部楼层 |阅读模式
声明:本文为斯人原创,全部为作者一一分析得之,有不对的地方望赐教。

博客地址:PHP技术博客在CSDN也会同步更新的哦.

欢迎转载,转载请注明出处



静态变量

它可以是 静态全局变量,如果不调用unset,那么这个静态变量会一直存在,直到程序退出时才由Zend内存管理来释放

它可以是 静态局部变量:在函数里定义,函数执行完后,该静态变量不会消失

它可以是 静态成员变量:在类里定义,它可以在所有类的对象中共享

例如



[php]

<?php

function test(){

static $a=1;

$a++;

}

test(); //$a=2

test();//$a=3

test();//$a=4

[/php]

最后 $a=4了..

下面我们从内核里面分析它

static不是一个函数 ,它是一个关键字 ,所以只能从LEX语法分析中来查找

打开 zend/zend_language_scanner.l 查找 static

找到代码

[c]
<ST_IN_SCRIPTING>"static" {
        return T_STATIC;
}
[/c]



是一个宏

再打开 zend/zend_language_pareser.l

搜 T_STATIC

找到代码


[c]
T_STATIC static_var_list ';'
[/c]



跟进 static_var_list

找到代码


[c]
static_var_list:
                static_var_list ',' T_VARIABLE { zend_do_fetch_static_variable(&$3, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
        |       static_var_list ',' T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$3, &$5, ZEND_FETCH_STATIC TSRMLS_CC); }
        |       T_VARIABLE  { zend_do_fetch_static_variable(&$1, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
        |       T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$1, &$3, ZEND_FETCH_STATIC TSRMLS_CC); }

;
[/c]



就是这里了..它由PHP的语法分析程序 解析成上面的代码

zend_do_fetch_static_variable 这个函数就是了

它在zend/zend_compile.c里定义

代码如下


[c]
void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC)
{
        zval *tmp;  //一个临时变量
        zend_op *opline;
        znode lval;
        znode result;

        ALLOC_ZVAL(tmp); //申请一块内存

        if (static_assignment) {
                *tmp = static_assignment->u.constant;
        } else {
                INIT_ZVAL(*tmp);
        }
        if (!CG(active_op_array)->static_variables) {//初始化静态变量的HASH 键值
                ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
                 //初始化HASH值
                zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
        }
        zend_hash_update(CG(active_op_array)->static_variables, varname->u.constant.value.str.val, varname->u.constant.value.str.len+1, &tmp, sizeof(zval *), NULL);

        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->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 = ZEND_FETCH_STATIC;
        result = opline->result;

        if (varname->op_type == IS_CONST) {
                zval_copy_ctor(&varname->u.constant);
        }
        fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */

        if (fetch_type == ZEND_FETCH_LEXICAL) {
                znode dummy;

                zend_do_begin_variable_parse(TSRMLS_C);
                zend_do_assign(&dummy, &lval, &result TSRMLS_CC);
                zend_do_free(&dummy TSRMLS_CC);
        } else {
                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;

/*      zval_dtor(&varname->u.constant); */
}
[/c]

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-359009-1-1.html 上篇帖子: php我的菜鸟入门经历 下篇帖子: PHP(二) Zend studio Xampp 安装
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表