<?php
class test
{
static $name="abc";
} echo test::$name;

1.巴斯科范式

class_statement:
variable_modifiers { CG(access_type) = Z_LVAL($.u.constant); } class_variable_declaration ';'
; member_modifier:
T_PUBLIC { Z_LVAL($$.u.constant) = ZEND_ACC_PUBLIC; }
| T_PROTECTED { Z_LVAL($$.u.constant) = ZEND_ACC_PROTECTED; }
| T_PRIVATE { Z_LVAL($$.u.constant) = ZEND_ACC_PRIVATE; }
| T_STATIC { Z_LVAL($$.u.constant) = ZEND_ACC_STATIC; }
| T_ABSTRACT { Z_LVAL($$.u.constant) = ZEND_ACC_ABSTRACT; }
| T_FINAL { Z_LVAL($$.u.constant) = ZEND_ACC_FINAL; }
; class_variable_declaration:
class_variable_declaration ',' T_VARIABLE { zend_do_declare_property(&$, NULL, CG(access_type) TSRMLS_CC); }
| class_variable_declaration ',' T_VARIABLE '=' static_scalar { zend_do_declare_property(&$, &$, CG(access_type) TSRMLS_CC); }
| T_VARIABLE { zend_do_declare_property(&$, NULL, CG(access_type) TSRMLS_CC); }
| T_VARIABLE '=' static_scalar { zend_do_declare_property(&$, &$, CG(access_type) TSRMLS_CC); }
; variable:
T_STRING T_PAAMAYIM_NEKUDOTAYIM base_variable { $$ = $; zend_do_fetch_static_member(&$$, &$ TSRMLS_CC); }
; base_variable:
T_VARIABLE { fetch_simple_variable(&$$, &$, TSRMLS_CC); }
;

理解版

class_statement:
variable_modifiers { CG(access_type) = Z_LVAL($.u.constant); } class_variable_declaration ';'
; member_modifier:
T_PUBLIC { Z_LVAL($$.u.constant) = ZEND_ACC_PUBLIC; }
| T_PROTECTED { Z_LVAL($$.u.constant) = ZEND_ACC_PROTECTED; }
| T_PRIVATE { Z_LVAL($$.u.constant) = ZEND_ACC_PRIVATE; }
| T_STATIC { Z_LVAL($$.u.constant) = ZEND_ACC_STATIC; }
| T_ABSTRACT { Z_LVAL($$.u.constant) = ZEND_ACC_ABSTRACT; }
| T_FINAL { Z_LVAL($$.u.constant) = ZEND_ACC_FINAL; }
; class_variable_declaration:
class_variable_declaration ',' T_VARIABLE { zend_do_declare_property(&$, NULL, CG(access_type) TSRMLS_CC); }
| class_variable_declaration ',' T_VARIABLE '=' static_scalar { zend_do_declare_property(&$, &$, CG(access_type) TSRMLS_CC); }
| T_VARIABLE { zend_do_declare_property(&$, NULL, CG(access_type) TSRMLS_CC); }
| T_VARIABLE '=' static_scalar { zend_do_declare_property(&$, &$, CG(access_type) TSRMLS_CC); }
; variable:
T_STRING T_PAAMAYIM_NEKUDOTAYIM T_VARIABLE { $$ = $; zend_do_fetch_static_member(&$$, &$ TSRMLS_CC); }
;

2.对于 static $name="abc"

组织propert_info结构体,将其存于为类中的property_info 这个HashTable中,

注意: value 这个值是存在类中的property_table中,其中key 为property_info中的offset

void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) /* {{{ */
{
zval *property;
ALLOC_ZVAL(property);
if (value) {
*property = value->u.constant;
} else {
INIT_PZVAL(property);
Z_TYPE_P(property) = IS_NULL;
}
zend_declare_property_ex(CG(active_class_entry), zend_new_interned_string(Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant) + , TSRMLS_CC), Z_STRLEN(var_name->u.constant), property, access_type, comment, comment_len TSRMLS_CC);
}
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type, const char *doc_comment, int doc_comment_len TSRMLS_DC) /* {{{ */
{
zend_property_info property_info, *property_info_ptr;
const char *interned_name;
ulong h = zend_get_hash_value(name, name_length+); if (access_type & ZEND_ACC_STATIC) {
//如果是静态成员变量,就使用relloc分配需要的内存,size(zval*)*ce->default_static_member_count是总共的内存
property_info.offset = ce->default_static_members_count++;
ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS); ce->default_static_members_table[property_info.offset] = property;
if (ce->type == ZEND_USER_CLASS) {
ce->static_members_table = ce->default_static_members_table;
}
} else {
property_info.offset = ce->default_properties_count++;
ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS);
ce->default_properties_table[property_info.offset] = property;
} interned_name = zend_new_interned_string(property_info.name, property_info.name_length+, TSRMLS_CC);
if (interned_name != property_info.name) {
if (ce->type == ZEND_USER_CLASS) {
efree((char*)property_info.name);
} else {
free((char*)property_info.name);
}
property_info.name = interned_name;
} property_info.flags = access_type;
property_info.h = (access_type & ZEND_ACC_PUBLIC) ? h : zend_get_hash_value(property_info.name, property_info.name_length+); property_info.ce = ce;
zend_hash_quick_update(&ce->properties_info, name, name_length+, h, &property_info, sizeof(zend_property_info), NULL);
return SUCCESS;
}
void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
{
znode class_node;
zend_llist *fetch_list_ptr;
zend_llist_element *le;
zend_op *opline_ptr;
zend_op opline; zend_do_fetch_class(&class_node, class_name TSRMLS_CC); if (result->op_type == IS_CV) {
init_op(&opline TSRMLS_CC); opline.opcode = ZEND_FETCH_W;
opline.result_type = IS_VAR;
opline.result.var = get_temporary_variable(CG(active_op_array));
opline.op1_type = IS_CONST; //opline->op1为 成员变量的值,result->u.op.var为fetch_simple_variable所获得的值
LITERAL_STRINGL(opline.op1, estrdup(CG(active_op_array)->vars[result->u.op.var].name), CG(active_op_array)->vars[result->u.op.var].name_len, );
CALCULATE_LITERAL_HASH(opline.op1.constant);
GET_POLYMORPHIC_CACHE_SLOT(opline.op1.constant); //class_node.op_type此时为IS_VAR
if (class_node.op_type == IS_CONST) {
opline.op2_type = IS_CONST;
opline.op2.constant =
zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
} else {
SET_NODE(opline.op2, &class_node);
}
GET_NODE(result,opline.result);
opline.extended_value |= ZEND_FETCH_STATIC_MEMBER;
opline_ptr = &opline; zend_llist_add_element(fetch_list_ptr, &opline);
}

zend_do_fetch_class 函数的运行

static int ZEND_FASTCALL  ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *class_name = opline->op2.zv;
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
EX_T(opline->result.var).class_entry = CACHED_PTR(opline->op2.literal->cache_slot);
} else {
EX_T(opline->result.var).class_entry = zend_fetch_class_by_name(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->op2.literal + , opline->extended_value TSRMLS_CC);
CACHE_PTR(opline->op2.literal->cache_slot, EX_T(opline->result.var).class_entry);
//记住 这里被缓存住了

}
}
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
zval *varname;
zval **retval; SAVE_OPLINE();
varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); zend_class_entry *ce;
ce = CACHED_PTR(opline->op2.literal->cache_slot);
retval = zend_std_get_static_property(ce, Z_STRVAL_P(varname), Z_STRLEN_P(varname), , ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC); }

找到成员变量

ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, const char *property_name, int property_name_len, zend_bool silent, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_property_info *property_info;
ulong hash_value; hash_value = zend_hash_func(property_name, property_name_len+); //即使这里的类是子类,子类的ce->properties_info的数据复制于父类的properties_info这个hash table
if (UNEXPECTED(zend_hash_quick_find(&ce->properties_info, property_name, property_name_len+, hash_value, (void **) &property_info)==FAILURE)) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name);
}
return NULL;
} if (UNEXPECTED(!zend_verify_property_access(property_info, ce TSRMLS_CC))) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name);
}
return NULL;
} if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) == )) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name);
}
return NULL;
} if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL) ||
UNEXPECTED(CE_STATIC_MEMBERS(ce)[property_info->offset] == NULL)) {
if (!silent) {
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name);
}
return NULL;
} return &CE_STATIC_MEMBERS(ce)[property_info->offset];
}

php类 静态变量赋值 static $name="abc"的更多相关文章

  1. PHP 类属性 类静态变量的访问

    php的类属性其实有两种,一种是类常量,一种是类静态变量.两种容易引起混淆. 如同静态类方法和类实例方法一样,静态类属性和实例属性不能重定义(同名),但静态属性可以和类常量同名. <?php c ...

  2. python类静态变量

    python的类静态变量直接定义在类中即可,不需要修饰符,如: 1 class Test: stc_attr = 1 def __init__(self,attr1,attr2): self.attr ...

  3. Spring/Spring boot中静态变量赋值

    情形1:静态变量为自动注入的对象 解决方案:设置两个变量,非静态变量使用@resource注入Bean,然后使用@PostConstruct在Spring初始化Bean成功后为静态变量赋值 @Comp ...

  4. c#静态变量赋值问题

    class Program { static int i = getNum(); int j = getNum(); ; static int getNum() { return num; } sta ...

  5. oc 基本语法 类 静态变量 常量

    // // ReViewClass.h // hellowWorld // 本类是oc复习练手类 // Created by hongtao on 2018/3/26. // Copyright © ...

  6. 静态变量符 static

    1.private是访问权限限定,static表示不要实例化就可以使用. (1)被static修饰的变量,叫静态变量或类变量,没有被static修饰的变量,叫实例变量. 对于静态变量在内存中只有一个拷 ...

  7. C++类静态变量的一种使用特例

    不同进程里的数据默认情况下是互不影响的. 静态变量是属于类本身的,它的所有实例可以共享这个静态变量,但是有个先天条件就是在同一个进程的情况下!!

  8. php 类静态变量 和 常量消耗内存及时间对比

    在对类执行100w次循环后, 常量最快,变量其次,静态变量消耗时间最高 其中: 常量消耗:101.1739毫秒 变量消耗:2039.7689毫秒 静态变量消耗:4084.8911毫秒 测试代码: cl ...

  9. [C/C++] 静态变量赋值问题 undefined reference to

    刚才在写代码的时候 用到了一个静态变量 然后在别人地方直接使用的时候 也就是 NetWork::Flag = 0; 像是这样使用的时候一直提示 undefined reference to 各种检查之 ...

随机推荐

  1. CentOS 6.4 中安装部署 Nutch 1.7

    1.配置SSH 自行查阅相关资料 2.安装JDK,配置Java环境 自行查阅相关资料 3.安装SVN [root@master ~]# yum install -y subversion 通过SVN签 ...

  2. C++ 编写 CorelDRAW CPG 插件例子(2)—ClearFill

    这是另一个例子: 贴上主要代码: #include "stdafx.h" #include <tchar.h> #import "libid:95E23C91 ...

  3. stm32之ADC学习

    1.stm32中采用的是逐次逼近型模拟数字方式,那么什么是逐次逼近呢? 逐次逼近的方式类似于二分法,以8位数据为例:当输入一个模拟量的时候,首先取这8位数的一半,即1000 0000,与模拟量比较,大 ...

  4. [译] ASP.NET 生命周期 – ASP.NET 上下文对象(八)

    使用 HttpResponse 对象 HttpResponse 对象是与 HttpRequest 对象相对应的,用来表示构建中的响应.它当中提供了方法和属性可供我们自定义响应,有一些在使用 MVC 视 ...

  5. Schtasks 命令详解

    管理计划任务 SCHTASKS /parameter [arguments] 描述:     允许管理员创建.删除.查询.更改.运行和中止本地或远程系统上的计划任务. 参数列表:     /Creat ...

  6. nginx+ tomcat集群+动静资源分离

    不知道为什么这个随便删不掉,写了也值显示一半一半不显示, 我把重新写了一遍: nginx + tomcat集群和动静资源分离

  7. office安装不了 “windows installer 服务不能更新一个或多个受保护的windows文件”

    出现这种情况可能是系统中某些文件缺失了,一般发生于安装GHOST版或做过精简的系统 打开C:\WINDOWS\msagent 看看文件夹中内容是不是如下图所示: 再打开C:\Program Files ...

  8. 11个好用的jQuery拖拽拖放插件

    这次我们整理一些拖拽播放类型的jQuery插件,这些可能不是很常用,但偶尔会有网站设计项目用到,特别是后台相关的开发项目,这个拖放排序功能一般都会有,所以适合大家收藏起来,方便日后使用.接下来一起看盾 ...

  9. [转载]面向对象设计(OOD)思想(C#)

    有了思想才能飞翔,缺乏灵活就象少了轮子的汽车,难以飞奔.为了更好的理解设计思想,结合一个尽可能简洁的实例来说明OOD.设计模式及重构.通过下面的代码,详细地阐述面向对象设计思想. 一.传统过程化设计思 ...

  10. uva 10892

    试了一下纯暴力  结果过了 无话可说  应该有更好的方法...... /**************************************************************** ...