静态变量

它可以是 静态全局变量,如果不调用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. keepalived之vrrp_script详解

    通常情况下,利用keepalived做热备,其中一台设置为master,一台设置为backup.当master出现异常后,backup自动切换为master.当backup成为master后,mast ...

  2. DVI与VGA有什么区别

    [DVI与VGA有什么区别] DVI接口的传输信号采用全数字格式,与之对应的是采用模拟信号的VGA接口. VGA和DVI的区别,首先VGA模拟信号的传输比较麻烦,首先是将电脑内的数字信号转换为模拟信号 ...

  3. ThreadLocal原理深入解析

    目录 1. 从一次项目经历说起 2. ThreadLocal源码解析 2.1 set方法源码解析 2.2 get方法源码解析 2.3 ThreadLocal源码总结 3. ThreadLocalMap ...

  4. Ajax工作原理和原生JS的ajax封装

    前言: 之所以用ajax作为博客的开篇,是因为无论从ajax的出现还是从它的作用上来说,ajax对于前端无疑是意义重大的.甚至可以说,是ajax带来了前端这个行业.当然,历史并不能说明当下,曾经的辉煌 ...

  5. Quaternion.identity是什么意思?

    Quaternion.identity就是指Quaternion(0,0,0,0),

  6. [C++] Realloc Memory

      函数说明 void* realloc (void* ptr, size_t size); 语法 指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小). 新的大小可大可小(但是要 ...

  7. linux查看操作系统版本信息

    linux查看操作系统版本信息  摘自:https://www.cnblogs.com/vaelailai/p/7545166.html 一.linux下如何查看已安装的centos版本信息: 1.L ...

  8. 【转】彻底理解ThreadLocal

    ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  9. Exception (1) Understanding Exception Handling

    When an exception is thrown, it cannot be ignored--there must be some kind of notification or termin ...

  10. 在 Linux 系统上快速获取命令的帮助信息

    几种方法: help 命令 man 命令 info 命令 命令 --help man 章节分类如下 1 - commands 2 - system calls 3 - library calls 4 ...