Q1: "how to modify this line to reproduce the behavior of PHP" A1:
/* {{{ vendor_my_get_debug_info */ static HashTable* vendor_my_get_debug_info(zend_object *object, int *is_temp) { vendor_my *intern = ZOBJ_TO_VENDOR_MY(object); HashTable *debug_info=NULL, *std_props=NULL; *is_temp = 1; std_props = zend_std_get_properties(object); debug_info = zend_array_dup(std_props); zval zdata; if (Z_ISREF(intern->data) && Z_REFCOUNT(intern->data)<2) {// If the reference is no longer used by the PHP-user ZVAL_COPY(&zdata, &Z_REF(intern->data)->val);// hide reference (for compatibility) } else { ZVAL_COPY(&zdata, &intern->data);// show reference (for debugging ???) } zend_hash_str_update(debug_info, "data", sizeof("data")-1, &zdata); return debug_info; } /* }}} */ Q2: "Why do I have to hide that it's a reference ?" A2: For historical( debugging) raison, see : https://github.com/php/php-src/blob/master/ext/standard/var.c#L202 I think it's a bad idea to show & but it doesn't really matter. In my case I think it's best never to show the reference : zval zdata; ZVAL_COPY(&zdata, Z_ISREF(intern->data) ? &Z_REF(intern->data)->val : &intern->data); zend_hash_str_update(debug_info, "data", sizeof("data")-1, &zdata); If I need to debug references/refcount it is better to use gdb's pretty-print feature but no var_dump() Le sam. 9 avr. 2022 à 17:51, Glash Gnome <glash.gn...@gmail.com> a écrit : > Out of politeness I answer myself, > > > PHP_FUNCTION(var_dump) > -> php_var_dump() > -> zend_std_get_properties_for() // Zend object > handler get_properties_for > -> obj->handlers->get_debug_info(obj, &is_temp); // Zend object > handler get_debug_info > -> zend_std_get_properties();// Zend object > handler get_properties > -> rebuild_object_properties() > -> _zend_hash_append_ind() > => ZVAL_INDIRECT(&p->val, ptr); // do the trick( > Z_TYPE change) > TODO: Find out how to manage the IS_INDIRECT > > So to reproduce the default php behavior I can implement the get_debug_info > handler. > > I'm still trying to figure out how to modify this line : > void my_get_debug_info() { > // ... > // Z_REFCOUNT(intern->data)==1 > // Z_TYPE(intern->data)==IS_REFERENCE > // Z_TYPE(Z_REF(intern->data)->val)==IS_ARRAY > zval zdata; ZVAL_COPY(&zdata, &intern->data);// Why do I have to hide > that it's a reference ? > zend_hash_str_update(debug_info, "data", sizeof("data")-1, &zdata); > // ... > return debug_info; > } > > my_handlers.get_debug_info = my_get_debug_info; > > > struct _my {// intern structure > zval data;// array of unsigned int > zend_object std; > }; > > Le sam. 9 avr. 2022 à 15:42, Glash Gnome <glash.gn...@gmail.com> a écrit : > >> Hello, >> >> I am developing a PHP extension. I can't reproduce the behavior of >> references of Zend/PHP. >> >> Here is some Code illustrating Zend's behavior: >> <?php >> class Foo { public $baz = array(1);} >> $foo = new Foo(); >> $ref = &$foo->baz; >> $foo->baz = [123];//set array has reference >> var_dump($foo); >> >> Output ------------------------ >> object(Foo)#1 (1) { >> ["baz"]=> >> &array(1) { [0]=> int(123) } >> } >> -------------------------------- >> Note the symbol ( &) output from the var_dump(); >> >> >> Now I add unset($ref) in my code >> <?php >> class Foo { public $baz = array(1);} >> $foo = new Foo(); >> $ref = &$foo->baz; >> //unset($ref);// kill reference >> $foo->baz = [123];// set array has reference >> unset($ref) ;// kill reference >> var_dump($foo); >> ------------------------ >> object(Foo)#1 (1) { >> ["baz"]=> >> array(1) { [0]=> int(123) } >> } >> -------------------------------- >> >> Note that the symbol (&) has disappeared from the output of var_dump(); >> >> I would like to reproduce this behavior but I don't know which method of >> zend_object_handlers allows to remove( Z_UNREF) the reference. >> >> Thank you for your help >> >> >>