3

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();
3
  • check for object cloning in PHP, what you are doing is not correct. Commented Jul 23, 2014 at 7:29
  • you can use PHP object Clone Commented Jul 23, 2014 at 7:30
  • 2
    It's just another way of creating a new object of the $a class that was introduced in PHP 5.3 Commented Jul 23, 2014 at 7:37

3 Answers 3

2
$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

Sign up to request clarification or add additional context in comments.

4 Comments

sad to see how bad programming is encouraged :( This could however be usefull for job interviews. To go along with all those fizzbuzz questions -.-
M'eh... wouldn't exactly call it "bad programming". Seems kind of like a "why not?" situation to me. I'm not sure of a situation where this would be extremely useful, but it's not like it makes no sense either.
true, but it confuses.
Not if you know what it does. ;P
1

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 (e.g. 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.

6 Comments

how is this an answer?
@Pinoniq The code does in fact work. I wouldn't say it should - but it does. I would wager if enough digging was done in the PHP code, somewhere in there if a variable cannot be converted to a string, when using variable variables, it uses the class of the object to instantiate another one.
hmm, what version of php are you using? and what engine? my script fails ($b is not of the same class as $a)
@Pinoniq PHP Version 5.3.10-1ubuntu3.8. Nothing funky with the build either - but the output of the script the OP gave is simply aaa no notices, no warnings, no errors. Oh, also Zend Scripting Language Engine: Zend Engine v2.3.0
@cubob Did some more experimenting. Looks like it is simply a new shorthand they added.
|
-1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.