zval_dtor和zval_ptr_dtor是2个宏函数,定义在(zend_variables.h):
#define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
#define zval_ptr_dtor(zval_ptr) _zval_ptr_dtor((zval_ptr) ZEND_FILE_LINE_CC) _zval_dtor也是定义在(
zend_variables.h
):
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC);
static inline void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
{
if (zvalue->type <= IS_BOOL) {
return;
}
_zval_dtor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
} _zval_dtor_func定义在(zend_variables.c):
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
{
switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
case IS_STRING:
case IS_CONSTANT:
CHECK_ZVAL_STRING_REL(zvalue);
STR_FREE_REL(zvalue->value.str.val);
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY: {
TSRMLS_FETCH();
if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
zend_hash_destroy(zvalue->value.ht);
FREE_HASHTABLE(zvalue->value.ht);
}
}
break;
case IS_OBJECT:
{
TSRMLS_FETCH();
Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
}
break;
case IS_RESOURCE:
{
TSRMLS_FETCH();
/* destroy resource */
zend_list_delete(zvalue->value.lval);
}
break;
case IS_LONG:
case IS_DOUBLE:
case IS_BOOL:
case IS_NULL:
default:
return;
break;
}
}
_zval_ptr_dtor定义在(zend_execute_API.c):
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
{
zval *zv = *zval_ptr;
#if DEBUG_ZEND>=2
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
#endif
Z_DELREF_P(zv);
if (Z_REFCOUNT_P(zv) == 0) {
TSRMLS_FETCH();
if (zv != &EG(uninitialized_zval)) {
GC_REMOVE_ZVAL_FROM_BUFFER(zv);
zval_dtor(zv);
efree_rel(zv);
}
} else {
TSRMLS_FETCH();
if (Z_REFCOUNT_P(zv) == 1) {
Z_UNSET_ISREF_P(zv);
}
GC_ZVAL_CHECK_POSSIBLE_ROOT(zv);
}
} 好了,结果就是一点 zval_ptr_dtor会调用zval_dtor来释放内容。所以不在使用某个zval变量的时候记得及时清除掉。