1

I've tried searching for this but frankly I don't know what to search for and unfortunately I imagine this question has been asked before.

In PHP, and possibly other languages, why can't I use an object immediately after I create it?

// This causes an error
$obj = new Object()->myFunction();

Note: I return $this in most of my setter functions so I can chain them together

function myFunction() {
    // ... some more code here ...

    return $this;
}
chrislondon
  • 12,487
  • 5
  • 26
  • 65

3 Answers3

6

It's simply invalid syntax in PHP. You are able to get this to work in PHP 5.4 by wrapping the object constructor expression with parentheses:

$obj = (new Object())->myFunction();

See PHP 5.4 new features:

  • Class member access on instantiation has been added, e.g. (new Foo)->bar().

If you want $obj to be the value of the new Object, be sure to return $this from Object::myFunction() (this is called method chaining).

An alternative for getting constructor chaining to work is to have a static method in your class which creates the new class instance for you:

class Object {
    public function __construct($var) {
        $this->var = $var;
    }
    public static function newObject($var) {
        return new Object($var);
    }
}

$obj = Object::newObject()->chainMethodX()->chainMethodY()->...
Community
  • 1
  • 1
  • worth noting here to that $obj will be populated with the return of myFunction... only will be the object if myFunction returns $this – Orangepill Jun 11 '13 at 19:43
  • Thanks @Orangepill I forgot to mention that in my question. I'll add it now – chrislondon Jun 11 '13 at 19:45
  • @Orangepill I wonder, how this weird syntax can be used. Constructors were invented for this. – user4035 Jun 11 '13 at 19:48
  • @Tim Cooper is there a difference between `(new Foo)->bar()` and `(new Foo())->bar()`? – chrislondon Jun 11 '13 at 19:48
  • @chrislondon: No. In both cases, they call the constructor for the class. –  Jun 11 '13 at 19:49
  • The manual makes no mention of the precedence associated with `->` but it must be that it is higher then `new`. The precedence order that is on the site puts new and clone on top. – Orangepill Jun 11 '13 at 19:54
2

This is invalid syntax.

PHP only supports:

$obj = new Object();
$obj->myFunction();

Keep in mind that, were you code sample to work, $obj would get the return value of myFunction().

Halcyon
  • 57,230
  • 10
  • 89
  • 128
1

Although not documented on the site it would appear as though the object operator -> has a higher precedence then the new keyword. So saying:

$obj = new Object()->someFunction();

is evaluated like you wrote

$obj = new (Object()->someFunction());

instead of the intended

$obj = (new Object())->someFunction();

The real reason it works this way is in the php grammer definition on line 775

Orangepill
  • 24,500
  • 3
  • 42
  • 63
  • You probably meant to link to [this line](http://lxr.php.net/xref/PHP_5_4/Zend/zend_language_parser.y#775). Declaring the T_NEW token is hardly "the real reason it works this way". – salathe Jun 11 '13 at 20:44