An exploration of small problems with PHP's new

高洛峰
Release: 2016-11-22 09:17:14
Original
1056 people have browsed it

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);
Copy after login

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}
Copy after login

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,
   }
Copy after login

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);
        } ...
        ...
}
Copy after login

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.


Related labels:
php
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!