zoukankan      html  css  js  c++  java
  • php unset变量

    <?php
     $a="abc";
     $b="def";
     unset($a,$b);
     echo $a."
    ";
     echo $b."
    ";

    1)词法分析

    <ST_IN_SCRIPTING>"unset" {
        return T_UNSET;
    }

    2)语法分析

    unticked_statement:

        |    T_UNSET '(' unset_variables ')' ';'          //unset($a,$b) 还能这么用呢,第一次知道 吐舌笑脸

    unset_variables:
            unset_variable
        |    unset_variables ',' unset_variable
    ;

    unset_variable:
            variable    { zend_do_end_variable_parse(&$1, BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1 TSRMLS_CC); }
    ;

    3)生成opcode

    void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */
    {
        zend_op *last_op;
    
        zend_check_writable_variable(variable);
    
        if (variable->op_type == IS_CV) {
            zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
            opline->opcode = ZEND_UNSET_VAR;
            SET_NODE(opline->op1, variable);
            SET_UNUSED(opline->op2);
            SET_UNUSED(opline->result);
            opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
        } else {
            //不是IS_CV类型的处理
        }
    }

    4)执行opcode

    static int ZEND_FASTCALL  ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
    {
        USE_OPLINE
        zval tmp, *varname;
        HashTable *target_symbol_table;
    
    
        SAVE_OPLINE();
        if (IS_CV == IS_CV &&
            IS_UNUSED == IS_UNUSED &&
            (opline->extended_value & ZEND_QUICK_SET)) {
    if (EG(active_symbol_table)) {
                zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.var);
    
                zend_delete_variable(EX(prev_execute_data), EG(active_symbol_table),  cv->name, cv->name_len+1, cv->hash_value TSRMLS_CC); //从active_symbol_table中清除cv->name以及相应值,再从CV数组中清除此值
                EX_CV(opline->op1.var) = NULL;
            } else if (EX_CV(opline->op1.var)) {
                zval_ptr_dtor(EX_CV(opline->op1.var));
                EX_CV(opline->op1.var) = NULL;
            }
            CHECK_EXCEPTION();
            ZEND_VM_NEXT_OPCODE();
        }
        //不会被执行了
    }
     
    #define CV_DEF_OF(i) (EG(active_op_array)->vars[i])

    #undef EX_CV
    #define EX_CV(var) EX(CVs)[var]
    #undef EX_CVs
    #define EX_CVs() EX(CVs)
    #undef EX_T
    #define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
    #undef EX_Ts
    #define EX_Ts() EX(Ts)

     

    ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */
    {
        if (zend_hash_quick_del(ht, name, name_len, hash_value) == SUCCESS) {
            name_len--;
            while (ex && ex->symbol_table == ht) {
                int i;

                if (ex->op_array) {
                    for (i = 0; i < ex->op_array->last_var; i++) {
                        if (ex->op_array->vars[i].hash_value == hash_value &&
                            ex->op_array->vars[i].name_len == name_len &&
                            !memcmp(ex->op_array->vars[i].name, name, name_len)) {
                            ex->CVs[i] = NULL;
                            break;
                        }
                    }
                }
                ex = ex->prev_execute_data;
            }
        }
    }

    ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag)
    {
        uint nIndex;
        Bucket *p;
    #ifdef ZEND_SIGNALS
        TSRMLS_FETCH();
    #endif

        IS_CONSISTENT(ht);

        if (flag == HASH_DEL_KEY) {
            h = zend_inline_hash_func(arKey, nKeyLength);
        }
        nIndex = h & ht->nTableMask;

        p = ht->arBuckets[nIndex];
        while (p != NULL) {
            if ((p->h == h)
                 && (p->nKeyLength == nKeyLength)
                 && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */
                     || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */
                HANDLE_BLOCK_INTERRUPTIONS();
                if (p == ht->arBuckets[nIndex]) {
                    ht->arBuckets[nIndex] = p->pNext;
                } else {
                    p->pLast->pNext = p->pNext;
                }
                if (p->pNext) k{
                    p->pNext->pLast = p->pLast;
                }
                if (p->pListLast != NULL) {
                    p->pListLast->pListNext = p->pListNext;
                } else {
                    /* Deleting the head of the list */
                    ht->pListHead = p->pListNext;
                }
                if (p->pListNext != NULL) {
                    p->pListNext->pListLast = p->pListLast;
                } else {
                    ht->pListTail = p->pListLast;
                }
                if (ht->pInternalPointer == p) {
                    ht->pInternalPointer = p->pListNext;
                }
                if (ht->pDestructor) {
                    ht->pDestructor(p->pData);
                }
                if (p->pData != &p->pDataPtr) {
                    pefree(p->pData, ht->persistent);
                }
                pefree(p, ht->persistent);
                HANDLE_UNBLOCK_INTERRUPTIONS();
                ht->nNumOfElements--;
                return SUCCESS;
            }
            p = p->pNext;
        }
        return FAILURE;
    }

  • 相关阅读:
    Hadoop(二)—— HDFS
    Hive(一)—— 启动与基本使用
    Flume(一) —— 启动与基本使用
    Kafka(四) —— KafkaProducer源码阅读
    Flink(一) —— 启动与基本使用
    Kafka(三) —— 集群监控
    Hadoop(一)—— 启动与基本使用
    Spark(二)—— 标签计算、用户画像应用
    二. python数组和列表
    一. python数据结构与算法
  • 原文地址:https://www.cnblogs.com/taek/p/3875524.html
Copyright © 2011-2022 走看看