静态变量

它可以是 静态全局变量,如果不调用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. 【总结整理】AI产品经理大会2017(转载)

    从企业大数据到企业 AI | 易观智慧院院长 李智 1.AI 不是目的,而是要了解 AI 是什么,真正意义上的强人工智能在前沿领域尚未取得突破,暂时只能在影视文学作品中去思考人机关系.机器人三定律在未 ...

  2. 在tomcat中的conf文件夹下找server.conf 配置如下代码,可省略项目名路径访问 如 localhost:8080 即可访问到项目

    <Context path="" docBase="C:\Workspaces\Projects\SLSaleSystem_dw\WebRoot" rel ...

  3. LoadRunner11学习记录一 -- 安装

    一.首先是安装,相关的下载文件如下: 安装文件:http://pan.baidu.com/s/1ntH0Rd3 破解补丁:http://pan.baidu.com/s/1hq2HRsK 汉化包:htt ...

  4. EZOJ #258

    传送门 分析 我们考虑一个点有多少中情况可以被删除 我们发现只有删除它自己和删祖先共$dep_i$中 所以每个点的答案就是$\frac{1}{dep_i}$ 代码 #include<iostre ...

  5. 【转】Comprehensive learning path – Data Science in Python

    Journey from a Python noob to a Kaggler on Python So, you want to become a data scientist or may be ...

  6. mosquitto配置通过ssl通信

    mosquitto配置通过ssl通信 摘自https://www.cnblogs.com/stin/p/9258211.html 注意项: For openssl >= 1.0.1 the va ...

  7. Spring Boot☞ 统一异常处理

    效果区:  代码区: package com.wls.integrateplugs.exception.dto; public class ErrorInfo<T> { public st ...

  8. Sprig 面试中 问及 DI,IOC, AOP

    面向切面编程,把散落在程序中的公共部分提取出来,做成切面类,这样的好处在于,代码的可重用,一旦涉及到该功能的需求发生变化,只要修改该代码就行,否则,你要到处修改,如果只要修改1.2处那还可以接受,万一 ...

  9. 1118 Lining Up

    题目链接: http://poj.org/problem?id=1118 题意: 给定n个点, 求在同一直线上的点最多的直线上点的数目. 解法: 简单题目, 规模比较小,  暴力搜索. #includ ...

  10. configparser模块读写ini配置文件

    在自动化测试过程中,为了提高脚本的可读性和降低维护成本,将一些通用信息写入配置文件,将重复使用的方法写成公共模块进行封装,使用时候直接调用即可. 这篇博客,介绍下python中利用configpars ...