break;
case IS_OBJECT:
{
- HashTable *properties = NULL;
+ HashTable *properties;
zstr class_name = NULL_ZSTR;
zend_uint clen;
+ int is_temp;
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
if (class_name.v) {
efree(class_name.v);
}
- if (Z_OBJ_HANDLER_P(expr, get_properties)) {
+ if (Z_OBJ_HANDLER_P(expr, get_debug_info)) {
+ properties = Z_OBJ_HANDLER_P(expr, get_debug_info)(expr, &is_temp TSRMLS_CC);
+ } else if (Z_OBJ_HANDLER_P(expr, get_properties)) {
properties = Z_OBJPROP_P(expr);
+ is_temp = 0;
+ } else {
+ break;
}
- if (properties) {
- if (++properties->nApplyCount>1) {
- ZEND_PUTS(" *RECURSION*");
- properties->nApplyCount--;
- return;
- }
- print_hash(properties, indent, 1 TSRMLS_CC);
+ if (++properties->nApplyCount>1) {
+ ZEND_PUTS(" *RECURSION*");
properties->nApplyCount--;
+ return;
+ }
+ print_hash(properties, indent, 1 TSRMLS_CC);
+ properties->nApplyCount--;
+ if (is_temp) {
+ zend_hash_destroy(properties);
+ efree(properties);
}
break;
}
called, we cal __call handler.
*/
-static HashTable *zend_std_get_properties(zval *object TSRMLS_DC)
+ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC)
{
zend_object *zobj;
zobj = Z_OBJ_P(object);
return zobj->properties;
}
+ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
+{
+ *is_temp = 0;
+ return zend_std_get_properties(object TSRMLS_CC);
+}
+
static zval *zend_std_call_getter(zval *object, zval *member TSRMLS_DC)
{
zval *retval = NULL;
zend_std_compare_objects, /* compare_objects */
zend_std_cast_object_tostring, /* cast_object */
NULL, /* count_elements */
+ NULL, /* get_debug_info */
};
/*
/* Used to get hash of the properties of the object, as hash of zval's */
typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC);
+typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TSRMLS_DC);
+
/* Used to call methods */
/* args on stack! */
/* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this.
zend_object_compare_t compare_objects;
zend_object_cast_t cast_object;
zend_object_count_elements_t count_elements;
+ zend_object_get_debug_info_t get_debug_info;
};
extern ZEND_API zend_object_handlers std_object_handlers;
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_uchar type, zstr property_name, int property_name_len TSRMLS_DC);
ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);
-
+ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC);
+ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC);
ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type, void *extra TSRMLS_DC);
PHPAPI void php_var_dump(zval **struc, int level, int verbose TSRMLS_DC)
{
- HashTable *myht = NULL;
+ HashTable *myht;
zstr class_name;
zend_uint class_name_len;
int (*php_element_dump_func)(zval**, int, va_list, zend_hash_key*);
+ int is_temp;
if (level > 1) {
php_printf("%*c", level - 1, ' ');
}
php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
php_element_dump_func = php_array_element_dump;
+ is_temp = 0;
goto head_done;
case IS_OBJECT:
- myht = Z_OBJPROP_PP(struc);
+ if (Z_OBJ_HANDLER_PP(struc, get_debug_info)) {
+ myht = Z_OBJ_HANDLER_PP(struc, get_debug_info)(*struc, &is_temp TSRMLS_CC);
+ } else if (Z_OBJ_HANDLER_PP(struc, get_properties)) {
+ myht = Z_OBJPROP_PP(struc);
+ is_temp = 0;
+ } else {
+ myht = NULL;
+ is_temp = 0;
+ }
if (myht && myht->nApplyCount > 1) {
PUTS("*RECURSION*\n");
return;
head_done:
if (myht) {
zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_element_dump_func, 3, level, verbose, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1));
+ if (is_temp) {
+ zend_hash_destroy(myht);
+ efree(myht);
+ }
}
if (level > 1) {
php_printf("%*c", level-1, ' ');
zend_uint class_name_len;
zend_class_entry *ce;
int (*zval_element_dump_func)(zval**, int, va_list, zend_hash_key*);
+ int is_temp;
if (level > 1) {
php_printf("%*c", level - 1, ' ');
zval_element_dump_func = zval_array_element_dump;
goto head_done;
case IS_OBJECT:
- myht = Z_OBJPROP_PP(struc);
+ if (Z_OBJ_HANDLER_PP(struc, get_debug_info)) {
+ myht = Z_OBJ_HANDLER_PP(struc, get_debug_info)(*struc, &is_temp TSRMLS_CC);
+ } else if (Z_OBJ_HANDLER_PP(struc, get_properties)) {
+ myht = Z_OBJPROP_PP(struc);
+ is_temp = 0;
+ } else {
+ myht = NULL;
+ is_temp = 0;
+ }
if (myht && myht->nApplyCount > 1) {
PUTS("*RECURSION*\n");
return;
}
- ce = Z_OBJCE(**struc);
- Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
+ ce = Z_OBJCE_PP(struc);
+ Z_OBJ_HANDLER_PP(struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);
php_printf("%sobject(%v)#%d (%d) refcount(%u){\n", COMMON, class_name, Z_OBJ_HANDLE_PP(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_PP(struc));
efree(class_name.v);
zval_element_dump_func = zval_object_property_dump;
head_done:
if (myht) {
zend_hash_apply_with_arguments(myht, (apply_func_args_t) zval_element_dump_func, 1, level, (Z_TYPE_PP(struc) == IS_ARRAY ? 0 : 1));
+ if (is_temp) {
+ zend_hash_destroy(myht);
+ efree(myht);
+ }
}
if (level > 1) {
php_printf("%*c", level-1, ' ');