Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is exactly happening when instantiating with 'new'?

Let's consider the following code:

class a {
    public $var1;
    function disp(){
        echo $this->var1;
        }    
    }

$obj1 = new a;
echo '<br/>After instantiation into $obj1:<br/>';    
xdebug_debug_zval('obj1');  

$obj1->var1 = "Hello ";
echo '<br/><br/>After assigning "Hello" to  $obj->var1:<br/>';
$obj1->disp();

echo "<br/><br/>";  
xdebug_debug_zval('obj1');  

The output:

After instantiation into $obj1:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }

After assigning "Hello" to $obj->var1:
Hello

obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }

One by one:

After instantiation into $obj1:
obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=2, is_ref=0)=NULL }

Why does $obj1->var1 have refcount=2 when there is only one object of class a?

Is it because of how the new operator makes assignment? PHP does assignment with references. When instantiated with new, no symbol/variable name is associated with that instance. But, the class properties do have names. Is the recount=2 because of this?

If that is the case then a C.O.W (copy on write) has occurred with a shallow copy WRT the class instance. While the properties are still pointing to the zval's of properties created during the instantiation using new.

Now,

After assigning "Hello" to $obj->var1:
Hello

obj1: (refcount=1, is_ref=0)=class a { public $var1 = (refcount=1, is_ref=0)='Hello ' }

So, when I assign a value to the property $obj1->var1 a new zval container for that property and hence the refcount=1?

Does this mean that the zval container created during instantiation using new still lives but cannot be accessed since there is no symbol / variable name associated with it?

Please note (from xdebug: Variable Display Features):
debug_zval_dump() is different from xdebug_debug_zval().

void xdebug_debug_zval( [string varname [, ...]] )

Displays information about a variable.

This function displays structured information about one or more variables that includes its type, value and refcount information. Arrays are explored recursively with values. This function is implemented differently from PHP's debug_zval_dump() function in order to work around the problems that that function has because the variable itself is actually passed to the function. Xdebug's version is better as it uses the variable name to lookup the variable in the internal symbol table and accesses all the properties directly without having to deal with actually passing a variable to a function. The result is that the information that this function returns is much more accurate than PHP's own function for showing zval information.

UPDATE : Dec 31th 2011:

I am trying to look at how memory allocation takes place when new is used. But There are too many other things I have to do right now. I hope I will be able to post an useful update soon. Until then here are the links to code at which I was looking at :

  • typedef union hdr
  • register pointer new = malloc (sizeof (header) + size);
  • expr_without_variable: T_NEW class_name_reference
  • function zend_do_fetch_class
like image 883
ThinkingMonkey Avatar asked Dec 29 '11 13:12

ThinkingMonkey


People also ask

What is difference between instantiating a C++ object using new vs New?

What is difference between instantiating a C++ object using new vs. without new? In C++, we can instantiate the class object with or without using the new keyword. If the new keyword is not use, then it is like normal object. This will be stored at the stack section.

What does it mean to instantiate in Python?

What is instantiate in Python? Should you leave more than $1,000 in a checking account? (Continue reading) The process of creating a new instance of a class is known as instantiation. In general, the syntax for instantiating an object is to invoke the constructor of a class.

How to create a new instance of a class?

The process of creating a new instance of a class is known as instantiation. In general, the syntax for instantiating an object is to invoke the constructor of a class. For example, if there were a class named Widget, we could create an instance of that class using a syntax such as w = Widget ( ), assuming that the constructor does


2 Answers

Adding another instantiation $obj2 = new a; increases the refcount to 3, not 4, so it's something which happens as a result of calling xdebug_debug_zval. The purpose of the xdebug function is to avoid the confusion from the passing the variable into the function and (possibly) creating an extra reference.

Unfortunately, this does not apply to the member variables; another reference is created to those zvals in order to export them. Therefore, all the caveats and confusing circumstances listed in the note on the debug_zval_dump documentation still apply for the member variables.

like image 191
cmbuckley Avatar answered Sep 27 '22 20:09

cmbuckley


I think the section "Note: Beware the refcount" on the following page explains this: http://php.net/manual/en/function.debug-zval-dump.php

It shows that the ref count increases if zend optimizes how it's passed, but then the "caveat" being when copy-on-write is invoked, returning the refcount back down to 1.

Hope that helps

like image 28
Homer6 Avatar answered Sep 27 '22 20:09

Homer6