Small questions about new PHP
Cause
Some people mentioned a question about new and stdClass in the group two days ago, as shown below:
This code can run correctly, and $ a and $ B are two different empty objects. Even if $ a is added and assigned a value to $ a before new $ a, $ B is always an empty object.
So the question is: why can empty objects still be behind new? is there anything special about stdClass?
Actual performance
In fact, we can know it with a little verification. In fact, this has nothing to do with stdClass. it is entirely determined by the new behavior. for example, we can perform a simple test on psysh:
>>> $a = new Reflection;=> Reflection {#174}>>> $b = new $a;=> Reflection {#177}Here I have a new Reflection class instance, which is similar to 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, }In this example, we can clearly see that changing the $ a attribute has no effect on $ B (here we can also consider a keyword of PHP: clone ).
Now that we know the performance, we can also draw a conclusion that a new object is equivalent to the class of the new original object through the object of a class.
Cause
So what kind of PHP implementation causes this kind of performance? Let's start with the source code to resolve this issue.
In fact, from the source code, we can go straight to zend_vm_def.h to find the answer. in the explanation of ZEND_FETCH_CLASS opcode, we can see the following content:
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); } ... ...}Remove the interference context. the above content clearly shows an explanation: If the obtained class_name is an object, find its class through the macro of Z_OBJCE_P. So the above expression is easy to explain.
This is a very simple problem, so you don't have to think about it. If you want to know the specific implementation of new, you can view the implementation of zend_compile_new in the zend_compile.c file.