“Operator” precedence? Why new Object()->method()

2019-07-29 14:21发布

Let's consider the following code:

<?php

class X{
    public function test(){
        return 'test';
    }
}

//This obviously works:
$x = (new X())->test();
//This does not, syntax error
$x = new X()->test();
echo $x;

Why?

BTW: I know it was introduced in php 5.4

It's not about "how", it's about "why" - I know the first syntax is the one documented in the manual. Actually, it's more about where and how to find the answer.

From what I've learned so far, while asking my questions elsewhere:

The -> is not actually an "operator", it's a "token" or "lexical token" - which doesn't help me much.

The first version is equal to saying: "new (DateTime()->format())" which obviously is bad. This suggest it's about "operator precedence", but #1 - the -> is not an operator (right?), and #2 - why isn't this documented anywhere?

BTW, on http://php.net/manual/en/language.operators.precedence.php we can read that the "new" operator associativity is neither left nor right, it's none, and we can also read "Operators of equal precedence that are non-associative cannot be used next to each other, for example 1 < 2 > 1 is illegal in PHP" so... if -> was an operator (and it was non-associative) then everything would be clear, but is it an operator? If it is, then why isn't it listed on the above list ( http://php.net/manual/en/language.operators.precedence.php )?

1条回答
放荡不羁爱自由
2楼-- · 2019-07-29 14:55

Because it's ambiguous, i.e. it can be interpreted in 2 different ways:

  • Call test() on a new X instance (the one that you want):

    $object = new X();
    $x      = $object->test();
    
  • Create a new instance of a class name returned by method test() on the object returned by function X():

    $object = X();
    $class  = $object->test();
    $x      = new $class();
    

Strangely enough, there's actually no way to write a one-liner for the second case ... the following won't work:

new (X()->test());   // syntax error
new (X()->test())(); // syntax error

But still, you get the idea.

查看更多
登录 后发表回答