|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #70549 Allow `new Foo()->bar()` without parens around `(new Foo)`
Submitted: 2015-09-22 07:04 UTC Modified: 2015-09-29 03:01 UTC
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: vovan-ve at yandex dot ru Assigned: yohgaki (profile)
Status: Assigned Package: Scripting Engine problem
PHP Version: 7.1.0 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: vovan-ve at yandex dot ru
New email:
PHP Version: OS:


 [2015-09-22 07:04 UTC] vovan-ve at yandex dot ru
PHP 5.4 allowed us to chain member assess to `new Foo`, but there must be parens:

    (new Foo)->bar();
    (new Foo(42, 37))->bar();
    something((new Foo(42, 37))->lorem()->ipsum()->dolor());

Why do we need that redundant parenses? Compare what ECMAScript allows - you know:

    new Foo().method();
    new Foo().field;
    new some.where.Foo().method();
    new Foos[i]().method();
    new (anything)().method();

PHP 7 should to remove redundant parens.

Test script:
class Foo {
    protected $id;
    public function __construct($id) {
        echo "new ", get_called_class(), "($id)\n";
        $this->id = $id;
    public function __toString() {
        return get_class($this) . "{" . $this->id . "}";
    public function bar($x) {
        echo $this, "->", __FUNCTION__, "($x)\n";
        return $this;
    public function val($x) {
        echo $this, "->", __FUNCTION__, "($x) => $x\n";
        return $x;
    public function lorem(self $foo, $x) {
        echo $this, "->", __FUNCTION__, "($foo, $x)\n";
        return $this;

new Foo(10)->bar(20)->bar(30)->bar(new Foo(40)->val(50));
new Foo(60)->lorem(new Foo(70)->bar(80), new Foo(90)->val(100));
// same as
// (new Foo(10))->bar(20)->bar(30)->bar((new Foo(40))->val(50));
// (new Foo(60))->lorem((new Foo(70))->bar(80), (new Foo(90))->val(100));

Expected result:
new Foo(10)
new Foo(40)
Foo{40}->val(50) => 50
new Foo(60)
new Foo(70)
new Foo(90)
Foo{90}->val(100) => 100
Foo{60}->lorem(Foo{70}, 100)

Actual result:
Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR)


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2015-09-22 15:38 UTC] enoquejoseneas at gmail dot com
Good idea. PHP need this feature, already available on Java and Javascript
 [2015-09-25 07:07 UTC]
-Status: Open +Status: Assigned -Assigned To: +Assigned To: nikic
 [2015-09-25 07:07 UTC]
(assigning to Nikita for his PoV on this)
 [2015-09-25 07:17 UTC]
-Assigned To: nikic +Assigned To:
 [2015-09-25 07:17 UTC]
We currently allow code like this:

    $obj = new $foo->bar();
    // Meaning:
    $class = $foo->bar;
    $obj = new $class();

You are proposing to interpret this as $obj = (new $foo)->bar() instead, which would break backwards compatibility.

This could have been changed as part of the UVS RFC, but I felt like this change would be too intrusive and the consequences rather weird. I expect something like `new $foo['bar']` to behave as `new {$foo['bar']}` not `(new $foo)['bar']`.
 [2015-09-25 07:24 UTC] vovan-ve at yandex dot ru
> You are proposing to interpret this as `$obj = (new $foo)->bar()` instead

No, it's not. `new $foo->bar()->method()`
is exactly `new ($foo->bar)()->method()`
like `new` is ECMAScript.
 [2015-09-25 08:13 UTC]
Ah, I think I get what you mean now. You only want to allow omission of parentheses if new is used with an argument list, correct?

I.e. `new Foo->bar()` will be forbidden, but `new Foo()->bar()` will be allowed and interpreted as `(new Foo())->bar()`?
 [2015-09-25 08:20 UTC] vovan-ve at yandex dot ru
nikic, Yes, right. `new Foo->bar()` start with `Foo->...` and it is "unexpected ->".
 [2015-09-25 13:57 UTC]
In that case it should be very easy to support this. Something along these lines: This allows `new Foo()->bar()`, `new Foo()->bar`, `new Foo()['bar']`. Adding it to callable vars as well would allow `new Foo()()`.

So from the technical side this is no problem. I don't know if we should actually allow it, as the syntax looks somewhat ambiguous. I'm neutral regarding that.

If we want this change, somebody should RFC it.
 [2015-09-29 03:01 UTC]
-PHP Version: 7.0.0RC3 +PHP Version: 7.1.0 -Assigned To: +Assigned To: yohgaki
 [2015-09-29 03:01 UTC]
Good news. I'll prepare RFC for 7.1.
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC