php类 静态变量赋值 static $name="abc"

 

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

echo test::$name;

 

1.巴斯科范式

class_statement:
        variable_modifiers { CG(access_type) = Z_LVAL($1.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(&$3, NULL, CG(access_type) TSRMLS_CC); }
    |    class_variable_declaration , T_VARIABLE = static_scalar    { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
    |    T_VARIABLE                        { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
    |    T_VARIABLE = static_scalar    { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
;

variable:
    base_variable_with_function_calls { $$ = $1; }
;

base_variable_with_function_calls:
    base_variable                { $$ = $1; }    
;

base_variable:
    static_member { $$ = $1; $$.EA = ZEND_PARSED_STATIC_MEMBER; }
;

static_member:
    class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$$, &$1 TSRMLS_CC); }
;

 

 

理解版

class_statement:
        variable_modifiers { CG(access_type) = Z_LVAL($1.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(&$3, NULL, CG(access_type) TSRMLS_CC); }
    |    class_variable_declaration , T_VARIABLE = static_scalar    { zend_do_declare_property(&$3, &$5, CG(access_type) TSRMLS_CC); }
    |    T_VARIABLE                        { zend_do_declare_property(&$1, NULL, CG(access_type) TSRMLS_CC); }
    |    T_VARIABLE = static_scalar    { zend_do_declare_property(&$1, &$3, CG(access_type) TSRMLS_CC); }
;

variable:
    T_STRING T_PAAMAYIM_NEKUDOTAYIM T_VARIABLE { $$ = $3; zend_do_fetch_static_member(&$$, &$1 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) + 1, 0 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+1);

    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+1, 0 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+1);

    property_info.ce = ce;
    zend_hash_quick_update(&ce->properties_info, name, name_length+1, h, &property_info, sizeof(zend_property_info), NULL);
    return SUCCESS;
}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。