rfc:variable_syntax_tweaks

This is an old revision of the document!


PHP RFC: Variable Syntax Tweaks

Introduction

The Uniform Variable Syntax RFC resolved a number of inconsistencies in PHP's variable syntax. This RFC intends to address a small handful of cases that were overlooked.

Proposal

Terminology

PHP supports four principal types of “dereferencing” operations:

  • Array: $foo[$bar], $foo{$bar}
  • Object: $foo->bar, $foo->bar()
  • Static: Foo::$bar, Foo::bar(), Foo::BAR
  • Call: foo()

A fully dereferencable construction is dereferencable by all four operations.

Interpolated and non-interpolated strings

Non-interpolated strings "foo" are currently considered fully dereferencable, i.e. constructions such as "foo"[0] or "foo"->bar() are considered legal (syntactically at least). However, interpolated strings "foo$bar" are non-dereferencable.

This RFC proposed to treat both types of strings consistently, i.e. "foo$bar"[0], "foo$bar"->baz() etc become legal.

This inconsistency was originally reported in the context of scalar objects.

Constants and magic constants

Constants are currently array-dereferencable, that is FOO[0] is legal. However, magic constants are non-dereferencable.

This RFC proposes to treat magic constants the same way as constants, that is, writing __FUNCTION__[0] etc becomes legal.

Constant dereferencability

Constants (and class constants) are currently special cased and only dereferencable under the [] operator (and do not even support the nominally equivalent {} operator).

This RFC proposes to make constants (and class constants) fully array and object dereferencable, i.e. to allow both FOO{0} and FOO->length() (the latter only being relevant in conjunction with scalar objects).

This makes the set of array-dereferencable and object-dereferencable operations strictly identical.

Class constant dereferencability

Currently static property accesses are array, object and static dereferencable. However, even with the change from the previous section, class constant accesses are only array and object dereferencable. This means that while Foo::$bar::$baz is legal, Foo::BAR::$baz is not.

This RFC proposes to make class constant accesses static derefencable as well, so that Foo::BAR::$baz and Foo::BAR::BAZ become legal.

It should be noted that the same is not possible for plain constants, as FOO::$bar already interprets FOO as a class name, not a constant name. Similarly, both types of constants cannot be call dereferenced, as FOO() is interpreted as a function name and Foo::BAR() as a static method call.

This inconsistency was originally reported on Twitter.

Arbitrary expression support for new and instanceof

Most syntactic constructions that normally require an identifier also accept a syntax variation that accepts an arbitrary expression. For the most part, this uses curly braces, such as in ${expr}, $foo->{expr}, FOO::{expr}(), etc. On the left-hand-side of an expression, parentheses are used instead, such as in (expr)::foo().

One place where arbitrary expressions are currently not supported are class names in new and instanceof (which are currently treated as syntactically same).

This RFC proposes to introduce the syntax new {expr} and $x instanceof {expr} respectively.

Instanceof alternatives

While for new there is just one possible syntax choice that is consistent with the overall syntax design, there are two additional possibilities for instanceof: One is to instead use $x instanceof (expr), which may make more sense, as instanceof essentially looks like a normal binary operator.

The second possibility is to relax the restrictions around the right-hand-side of instanceof entirely. This would involve treating it as a normal expression, and then reinterpreting plain constant accesses as class name references instead. I think that in principle this is a good option, but am concerned that it will cause issues in the future if we introduce generic type support, in which case a class name will no longer necessarily coincide with an ordinary expression.

Backward Incompatible Changes

There are not backwards incompatible changes, this RFC allows strictly more syntax than before.

Vote

Unless there are concerns regarding specific parts of the RFC, a monolithic vote will be used.

rfc/variable_syntax_tweaks.1578392136.txt.gz · Last modified: 2020/01/07 10:15 by nikic