静态变量

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

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

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

例如

  1. <?php
  2. function test(){
  3. static $a=1;
  4. $a++;
  5. }
  6. test(); //$a=2
  7. test();//$a=3
  8. test();//$a=4

最后 $a=4了..

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

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

打开 zend/zend_language_scanner.l 查找 static

找到代码

  1. <ST_IN_SCRIPTING>"static" {
  2. return T_STATIC;
  3. }

是一个宏
再打开 zend/zend_language_pareser.l
搜 T_STATIC
找到代码

  1. T_STATIC static_var_list ';'

跟进 static_var_list
找到代码

  1. static_var_list:
  2. static_var_list ',' T_VARIABLE { zend_do_fetch_static_variable(&$3, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
  3. |       static_var_list ',' T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$3, &$5, ZEND_FETCH_STATIC TSRMLS_CC); }
  4. |       T_VARIABLE  { zend_do_fetch_static_variable(&$1, NULL, ZEND_FETCH_STATIC TSRMLS_CC); }
  5. |       T_VARIABLE '=' static_scalar { zend_do_fetch_static_variable(&$1, &$3, ZEND_FETCH_STATIC TSRMLS_CC); }
  6. ;

就是这里了..它由PHP的语法分析程序 解析成上面的代码
zend_do_fetch_static_variable 这个函数就是了
它在zend/zend_compile.c里定义
代码如下

    1. void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC)
    2. {
    3. zval *tmp;  //一个临时变量
    4. zend_op *opline;
    5. znode lval;
    6. znode result;
    7. ALLOC_ZVAL(tmp); //申请一块内存
    8. if (static_assignment) {
    9. *tmp = static_assignment->u.constant;
    10. } else {
    11. INIT_ZVAL(*tmp);
    12. }
    13. if (!CG(active_op_array)->static_variables) {//初始化静态变量的HASH 键值
    14. ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    15. //初始化HASH值
    16. zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
    17. }
    18. 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);
    19. if (varname->op_type == IS_CONST) {
    20. if (Z_TYPE(varname->u.constant) != IS_STRING) {
    21. convert_to_string(&varname->u.constant);
    22. }
    23. }
    24. opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    25. opline->result.op_type = IS_VAR;
    26. opline->result.u.EA.type = 0;
    27. opline->result.u.var = get_temporary_variable(CG(active_op_array));
    28. opline->op1 = *varname;
    29. SET_UNUSED(opline->op2);
    30. opline->op2.u.EA.type = ZEND_FETCH_STATIC;
    31. result = opline->result;
    32. if (varname->op_type == IS_CONST) {
    33. zval_copy_ctor(&varname->u.constant);
    34. }
    35. fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    36. if (fetch_type == ZEND_FETCH_LEXICAL) {
    37. znode dummy;
    38. zend_do_begin_variable_parse(TSRMLS_C);
    39. zend_do_assign(&dummy, &lval, &result TSRMLS_CC);
    40. zend_do_free(&dummy TSRMLS_CC);
    41. } else {
    42. zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    43. }
    44. CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
    45. /*      zval_dtor(&varname->u.constant); */
    46. }

PHP内核研究 静态变量的更多相关文章

  1. 深入理解PHP内核(九)变量及数据类型-静态变量

    原文链接:http://www.orlion.ga/251/ 通常静态变量是静态分配的,他们的生命周期和程序的生命周期一样长,只有在程序退出后才结束生命周期,这和局部变量相反,有的语言中全局变量也是静 ...

  2. [转]Android静态变量的生命周期

    原文地址:https://my.oschina.net/jerikc/blog/137207 Android是用Java开发,其静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的 ...

  3. 深入了解C#中的静态变量和静态构造函数

    深入的剖析C#中静态变量和静态构造函数: 在日常的程序开发过程经常会使用到静态变量,众所周知,静态变量时常驻内存的变量,它的生命周期是从初始化开始一直到Application结束.但是,我们经常会忽略 ...

  4. PHP内核探索之变量(7)- 不平凡的字符串

    切,一个字符串有什么好研究的. 别这么说,看过<平凡的世界>么,平凡的字符串也可以有不平凡的故事.试看: (1)       在C语言中,strlen计算字符串的时间复杂度是?PHP中呢? ...

  5. PHP内核探索之变量(4)- 数组操作

    上一节(PHP内核探索之变量(3)- hash table),我们已经知道,数组在PHP的底层实际上是HashTable(链接法解决冲突),本文将对最常用的函数系列-数组操作的相关函数做进一步的跟踪. ...

  6. PHP内核探索之变量(1)Zval

    作为数据的容器,我们常常需要跟变量打交道,不管这个变量是数字.数组.字符串.对象还是其他,因而可以说变量是构成语言的不可或缺的基础.本文是PHP内核探索之变量的第一篇,主要介绍zval的基本知识,包括 ...

  7. Android进程管理及静态变量垃圾回收

    1.Android静态变量的生命周期 静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的时候分配内存的,并且存在于方法 区.当类被卸载的时候,静态变量被销毁. 在PC机的客户端程 ...

  8. Android静态变量使用陷阱

    静态变量大家再熟悉不过了,本来没什么好重复的.事情起因是这样的,最近测试那边反应正在做的一个产品总是莫名其妙的显示不出某些数据,甚至闪退崩溃,仔细查了几遍发现没什么问题,最后百般周折发现在那部测试机上 ...

  9. 常量和静态变量会先载入内存后在进行执行php代码

    static $test=1;//在php执行前就已经写入内存$test++;var_dump($test);static $test=10;//在php执行前就已经写入内存var_dump($tes ...

随机推荐

  1. 什么是展uv

    uvw是对应三维模型x.y.z坐标,就像模型的皮肤一样,为了便于绘制贴图,需要将UV尽量展平 展UV就是把你建好的模型展开成平面,别人就可以在那平面上做材质,皮肤等,这些东西.例如展一个正方体的UV, ...

  2. selenium+jenkins网页自动化测试的构建

    jenkins+selenium可以做到对web自动化的持续集成. Jenkins的基本操作: 一.新建视图及job 新建视图: 新建job: 可以选择构建一个自由风格的软件项目或者复制已有的item ...

  3. th:onclik()传参问题(前端使用了bootstrap)

    网上大多帖子是这么写的 onclick调javascript函数时,不能直接使用onclick=“editUser(${prod.id})”,这样会报错,需要修改成如下的格式. <a href= ...

  4. SUSE Linux 多路径软件+LVM+裸设备的配置

    1.先要查出光纤卡的WWN号,SUSE 10下光纤卡的WWD在/sys/class/fc_host/host5/port_name文件中,有两块卡就会有两个host*的目录 接好光纤后可以在dev下可 ...

  5. SQLSERVER中常用的系统视图

    QLServer中提供了相当丰富的系统视图,能够从宏观到微观,从静态到动态反应数据库对象的存储结果.系统性能.系统等待事件等等.同时 也保留了与早期版本兼容性的视图,主要差别在于SQLServer20 ...

  6. loadrunner录制时web时,ie报安全证书问题

    解决方法:在Recording_Options下Port Mapping>Capture level设置为 WinNet level data Capture Level的设置说明:1.Sock ...

  7. [C++] Function Template - optional parameter

    Function Template

  8. Python使用日常

    #Python中文件夹和文件的判断import os My_Path = "/home/lpworkstudy/Gooddir/" #现在我们判断这个文件夹是否存在 #如果不存在, ...

  9. unity小记

    1.window下的Occlusion Culling是实现遮挡剔除效果,即不再摄像机里出现的物体使其不被渲染. 这样做要使物体为静态的,而且效果在设计时只在Occlusion面板下有效 2.wind ...

  10. 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释

    建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...