鍍金池/ 問答/PHP  C  網(wǎng)絡(luò)安全/ PHP源碼的疑問

PHP源碼的疑問

看到兩段代碼:

// 第一段代碼
int symbols;
do {
    symbols = zend_hash_num_elements(&EG(symbol_table));
    zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC);
} while (symbols != zend_hash_num_elements(&EG(symbol_table)));

// 第二段代碼
zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC);

這段代碼的意思是不是 反向遍歷 symbol_table ,然后把每個需要執(zhí)行析構(gòu)函數(shù)的 zval 扔到 TSRMLS_CC 里,這家伙就是一個數(shù)組了,然后作為 zend_objects_store_call_destructors 函數(shù)的參數(shù),zend_objects_store_call_destructors函數(shù)內(nèi)部再遍歷它(TSRMLS_CC)?
是這樣嗎?謝謝諸位

回答
編輯回答
寫榮

1.反向遍歷全局符號表
2.對符號表中的每一個元素應(yīng)用zval_call_destructor函數(shù)
3.判斷符號表中值的類型,如果是對象,則將其zval置為IS_UNDEF
4.遍歷對象棧,逐個執(zhí)行對象的析構(gòu)函數(shù)

判斷符號表中的元素的類型,如果是對象,則返回ZEND_HASH_APPLY_REMOVE,后續(xù)清理相應(yīng)的zval,有相應(yīng)的析構(gòu)函數(shù)則執(zhí)行
static int zval_call_destructor(zval *zv) /* {{{ */
{
    if (Z_TYPE_P(zv) == IS_INDIRECT) {
        zv = Z_INDIRECT_P(zv);
    }
    if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
        return ZEND_HASH_APPLY_REMOVE;
    } else {
        return ZEND_HASH_APPLY_KEEP;
    }
}

更新---------------------------------------------
在symbol的上一段,設(shè)置了符號表的析構(gòu)函數(shù)

if (CG(unclean_shutdown)) {
    EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
}

在反向遍歷符號表的過程中,如果引用計數(shù)減為0,對其存儲的zval執(zhí)行析構(gòu)函數(shù)
這個函數(shù)又調(diào)用了zend_objects_store_del
功能是先執(zhí)行對象的析構(gòu)函數(shù),然后釋放對象占用的內(nèi)存

2018年1月29日 02:47