静态变量

它可以是 静态全局变量,如果不调用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. 阿里巴巴Java开发规约扫描插件-Alibaba Java Coding Guidelines 在idea上安装使用教程

    经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的<阿里巴巴Java开发规约>扫描插件!该插件由阿里巴巴P3C项目组研发.P3C是世界知名的反潜机,专门对付 ...

  2. fsync性能问题

    最近在测试种发现程序里调用fsync刷文件到磁盘时,开销只有几百微秒,于是对fsync相关机制进行了一番调查. 磁盘(或RAID卡)自身通常会有硬件缓存机制,对于写操作,有write back和wri ...

  3. IDEA 提示找不到 javax 等 tomcat 的相关包

    网上很多方法都告诉你,把 javax 的 libs 拷贝到项目下吧,简直简单粗暴.其实有更好的办法. 1.首先进入 Run 其中的 Run/Debug Configurations,在 Server ...

  4. 554. Brick Wall最少的穿墙个数

    [抄题]: There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. ...

  5. 669. Trim a Binary Search Tree修剪二叉搜索树

    [抄题]: Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so ...

  6. DNS处理模块dnspython

    一.介绍 官网:http://www.dnspython.org/ https://pypi.org/project/dnspython/ dnspython是Python的DNS工具包.它支持几乎所 ...

  7. Java 代理机制

    Table of Contents 1 引言 2 常见的代理 3 代理模式UML图 4 代理模式实例 5 java动态代理 5.1 java动态代理UML图 6 代理模式与装饰者模式的区别 6.1 装 ...

  8. python 多继承详解-乾颐堂

    1 2 3 4 5 6 7 8 9 10 class A(object):    # A must be new-style class    def __init__(self):     prin ...

  9. zigbee之IAR环境搭建

    注册机第一个要选择: 为什么? 之前说CC2530是支持zigbee协议的无线芯片,其实它是这款硬件上有一个支持zigbee协议的无线电路,不仅有这款电路,而且还有一块cpu电路,它就是8051cpu ...

  10. 3.1.2 condition 条件

    package 第三章.重入锁; import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Reent ...