在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/PHP  C  網(wǎng)絡安全/ 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í)行析構函數(shù)的 zval 扔到 TSRMLS_CC 里,這家伙就是一個數(shù)組了,然后作為 zend_objects_store_call_destructors 函數(shù)的參數(shù),zend_objects_store_call_destructors函數(shù)內部再遍歷它(TSRMLS_CC)?
是這樣嗎?謝謝諸位

回答
編輯回答
寫榮

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

判斷符號表中的元素的類型,如果是對象,則返回ZEND_HASH_APPLY_REMOVE,后續(xù)清理相應的zval,有相應的析構函數(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ù)

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

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

2018年1月29日 02:47