简体   繁体   中英

PHP new operator with object reference

How is possible to use the "new" operator to create a new object using another object reference instead of a class name? Look at how $b is created...$a is a reference to an object.

code example:

class test {
    function aaa() {echo "aaa";}

}


$a = new test();
$b = new $a();
$b->aaa();
$a = new Foo;
$b = new $a;

This is just a shorthand notation, meaning create a new object of the same class as $a is an instance of. It's not cloning or copying or anything else.

It's the same kind of shorthand as:

$foo = new Foo;
echo $foo::BAR;

The "correct" syntax to use a class constant would be Foo::BAR , but $foo refers to the class, so using $foo::BAR is a convenience shorthand. In fact, it's more than that, it enables polymorphism by allowing your object instances to be substituted and your code to dynamically refer to possibly overridden constants in those substitutions. new $foo is the same kind of thing, it allows you to dynamically instantiate classes without necessarily knowing exactly what class that is.

Not that that's necessarily a great idea, but it may be useful sometimes.

These mechanics were introduced in PHP 5.3: http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new

This works perfectly well due to PHP's variable variable functions/nightmares/godsends.

http://php.net/manual/en/language.variables.variable.php

From the docs on it (much more articulated than I could do):

Class properties may also be accessed using variable property names. The variable property name will be resolved within the scope from which the call is made. For instance, if you have an expression such as $foo->$bar, then the local scope will be examined for $bar and its value will be used as the name of the property of $foo. This is also true if $bar is an array access.

Curly braces may also be used, to clearly delimit the property name. They are most useful when accessing values within a property that contains an array, when the property name is made of mulitple parts, or when the property name contains characters that are not otherwise valid (eg from json_decode() or SimpleXML).

In this case, it seems that even though the object $a cannot be converted to a string through an echo $a; statement, the code is manipulating it to test when creating the new class - assuming it is due to it being an instance of class test already.

I wouldn't recommend this sort of use of variable variables though, much too confusing and non intuitive?

Okay, I did some more digging around and experimenting. It looks like it is simply shorthand for the clone function in 5.3:

 <?php class test { public $inc=0; public function __construct() { $this->inc++; } function aaa() {echo $this->inc."<br>";} } $a = new test(); $a->aaa(); $b = new $a(); $b->aaa(); $a->inc=5; $a->aaa(); $c = new $a(); $c->aaa(); $d= clone $b; $d->aaa(); ?> 

Output:

 1 1 5 1 1 

So, the values aren't copied, but the constructor is used as normal.

In fact you cannot do it because there is no point.

If you use reference you point to some object and using new you create new object.

So syntax:

$b = new & $a();

won't work because it doesn't have any sense.

In above code $a is not reference. It's just an object of test. And $b is also object of test not reference and not copy of $a

<?php
class test {
    public $x = 20;

    function aaa() {echo "aaa";}

}


$a = new test();
$a->x = 10;
$b = new $a();
echo $b->x."<br />";
echo $a->x."<br />";
$a->x = 30;
echo $b->x."<br />";
echo $a->x."<br />";

var_dump($a);
var_dump($b);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM