Cause of the problem
Someone asked a question about new and stdClass in the group two days ago. The specific performance is as follows:
<?php $a = new stdClass; $b = new $a; var_dump($a, $b);
This code can run correctly, and $a and $b are two different spaces. object. Even if attributes are added and values are assigned to $a before new $a , $b is always an empty object.
So the question is: why can empty objects follow new? Is there anything special about stdClass?
Actual performance
In fact, it can be known with a little verification. In fact, this has nothing to do with stdClass. It is completely determined by the behavior of new. For example, do a simple test on psysh:
>>> $a = new Reflection; => Reflection {#174} >>> $b = new $a; => Reflection {#177}
I am new here An instance of the Reflection class behaves no differently than stdClass. Of course, you can also customize a class:
>>> class Test { public $foo = 1; } => null >>> $a = new Test => Test {#178 +foo: 1, } >>> $a->foo = 2; => 2 >>> $b = new $a; => Test {#180 +foo: 1, }
From this example, we can clearly see that changing the attributes of $a has no effect on $b (you can also think about a keyword in PHP here: clone).
Now that we already know the performance, we can also draw the conclusion: creating a new object through an object of a class new is equivalent to new the class of the original object.
Cause
So what kind of implementation of PHP causes this behavior? Let’s start with the source code to analyze this problem.
In fact, from the source code, we can go straight to zend_vm_def.h to find the answer. In the explanation of the opcode ZEND_FETCH_CLASS, we can see the following:
ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV) { ... if (OP2_TYPE == IS_CONST) { ... } else if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } ... ... }
Removing some interfering context, the above content is clearly presented Here is an explanation: If the obtained class_name is an object, find its class through the Z_OBJCE_P macro. So the above performance is easy to explain.
This itself is a very simple question, no need to think about it complicated. If you want to know the specific implementation of new, you can go to the zend_compile.c file to view the implementation of zend_compile_new.