rfc:new_without_parentheses

This is an old revision of the document!


PHP RFC: new MyClass()->method() without parentheses

Introduction

The “Class member access on instantiation” feature was introduced in PHP 5.4.0. Since then methods, properties and constants can be accessed on a newly created instance without an intermediate variable, but only if the new expression is wrapped in parentheses:

class MyClass
{
    public function method(): void
    {
        echo 'Hello, World!';
    }
}
 
(new MyClass())->method(); // Hello, World!
 
new MyClass()->method(); // PHP Parse error: syntax error, unexpected token "->"

The goal of this RFC is to enable the second sytax without parentheses to:

  • make coding with PHP more convenient,
  • lower the learning curve,
  • decrease the visual debt,
  • ease transition from other C-like languages that don't require parentheses (Java, C#, TypeScript).

Ambiguity?

At first glance new MyClass()->method() expression might seem ambiguous. But according to the same logic new MyClass() is also ambiguous: is it new (MyClass()) or new MyClass? However, such ambiguity does not exist: new MyClass() is interpreted as an instantiation of class MyClass with zero constructor arguments, not as instantiation of MyClass() function call result.

Here's how it is solved at the grammar level. The formula for the new expression is T_NEW class_name|new_variable|(expr) ctor_arguments, where new_variable is a variable expression without calls. Thus PHP offers 3 ways to provide a class:

// class_name
new MyClass();
 
// new_variable
new $class();
 
// (expr)
new (trim(' MyClass '))();

This guarantees that the new expression is unambiguous: once the parser encounters T_NEW, it considers whatever comes next a class name. Hence it's safe and unambiguous to further use the new expression on its own without parentheses. It's like refactoring (MyClass::new())->method() to MyClass::new()->method(). Nobody will ever read it as MyClass::(new())->method() or MyClass::(new()->method()).

Proposal

TODO

Backward Incompatible Changes

None.

Proposed PHP Version(s)

PHP 8.4

rfc/new_without_parentheses.1703862885.txt.gz · Last modified: 2023/12/29 15:14 by vudaltsov