静态变量

它可以是 静态全局变量,如果不调用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. SpringBoot整合ActiveMQ快速入门

    Spring Boot 具有如下特性: 为基于 Spring 的开发提供更快的入门体验 开箱即用,没有代码生成,也无需 XML 配置.同时也可以修改默认值来满足特定的需求. 提供了一些大型项目中常见的 ...

  2. 在zookeeper集群的基础上,搭建伪solrCloud集群

    伪集群的搭建:将solrCloud搭建到同一台机器上. 准备工作 1 将在window中部署的单机版solr上传到服务器(虚拟机)中 solr的简单部署:在tomcat中启动slor 的内容 这一次放 ...

  3. SpringMVC单元测试-MockMvc

    一 简介 MockMvc实现对Http请求的模拟,可以方便对Controller进行测试,使得测试速度快.不依赖网络环境,而且提供验证的工具,使得请求的验证统一而且很方便.   二 常见使用方式 1  ...

  4. Linux系统profile、bashrc、bash_profile等环境设置文件的使用

    一.前言 关于bash的环境设置文件,分为系统设置和个人设置,一般来说建议用户直接修改个人的设置. 本文测试环境为:centos6.5. 二.系统设置值 1. /etc/sysconfig/i18n ...

  5. 为什么丑陋的UI界面却能创造良好的用户体验?

    本文内容由Mockplus团队翻译. 官网:http://www.mockplus.cn 网站界面过于漂亮可能会影响网站的可用性,但本文中提到的5个网站界面可谓是“丑”出了新高度.这样的网站它还有可用 ...

  6. ant+proguard签名打包 .jar

    ant+proguard签名打包 .jar 摘自: https://blog.csdn.net/a_ycmbc/article/details/53432812 2016年12月02日 14:52:3 ...

  7. CSS3 圆环状进度条

    HTML: <div class="wrap"> <div class="progress-radial progress-25"> & ...

  8. Spring5源码解析-论Spring DispatcherServlet的生命周期

    Spring Web框架架构的主要部分是DispatcherServlet.也就是本文中重点介绍的对象. 在本文的第一部分中,我们将看到基于Spring的DispatcherServlet的主要概念: ...

  9. 两个SSH2间免密码登录

    SSH2免密码登录OpenSSHhttp://blog.csdn.net/aquester/article/details/23836299 OpenSSH免密码登录SSH2http://blog.c ...

  10. Matlab SLAM

    https://www.baidu.com/s?wd=Matlab%20SLAM&rsv_spt=1&rsv_iqid=0xfacaed5e00006d4e&issp=1&am ...