rfc:deprecate_dollar_brace_string_interpolation

This is an old revision of the document!


PHP RFC: Deprecate ${} string interpolation

  • Date: 2021-03-13
  • Author: Ilija Tovilo, tovilo.ilija@gmail.com
  • Status: Draft
  • Target Version: PHP 8.1
  • Implementation: TBD

Proposal

PHP allows embedding variables in strings with double-quotes (") and heredoc in various ways.

1. Directly embedding variables ("$foo")
2. Braces outside the variable ("{$foo}")
3. Braces after the dollar sign ("${foo}")
4. Dynamic variable lookup ("${expr}")

Unfortunately, all of these have their drawbacks but options 3 and 4 are by far the worst, particularly because they share the exact same syntax. This RFC proposes to deprecate options 3 and 4 in PHP 8.1 and remove them in PHP 9.0.

Status quo

Options 1, 2 and 3

Options 1, 2 and 3 all roughty try to do they same thing: They embed a local variable in a string, sometimes allowing to call a method or access an array offset on that variable. All of these examples are equivalent.

$foo = 'foo';
var_dump("$foo");
var_dump("{$foo}");
var_dump("${foo}");

All of the three options allow accessing an array offset. Unfortunately, the syntax is not consistent.

$foo = ['bar' => 'bar'];
var_dump("$foo[bar]");
var_dump("{$foo['bar']}");
var_dump("${foo['bar']}");

Only syntax 1 and 2 allow accessing properties.

$foo = (object) ['bar' => 'bar'];
var_dump("$foo->bar");
var_dump("{$foo->bar}");

Only syntax 2 allows calling methods.

class Foo {
    public function bar() {
        return 'bar';
    }
}
 
$foo = new Foo();
var_dump("{$foo->bar()}");

Only syntax 2 allows chaining all of the above.

class Bar {
    public function baz() {
        return 'baz';
    }
}
 
$foo = ['bar' => new Bar()];
var_dump("{$foo['bar']->baz()}");

Option 4

PHP has a feature called Variable variables. It allows you to get a variable by name. The name can be a string stored in another variable.

$foo = 'Hello world!';
$bar = 'foo';
var_dump(${$bar});

The same works within strings. This is the option 4 described above.

$foo = 'world!';
$bar = 'foo';
var_dump("Hello ${$bar}");

As you might notice, this syntax clashes with option 3. If the term between the two braces is not compatible with option 3 PHP will interpret it as option 4 which has completely different semantics.

const foo = 'bar';
$foo = 'foo';
$bar = 'bar';
 
var_dump("${foo}");
//> foo
 
var_dump("${(foo)}");
//> bar

The braces switch from option 3 to 4 because braces are not allowed in option 3. This means foo is no longer interpreted as a variable but as a constant, and option 4 will then try to find a local variable by the name of that constant. This is incredibly unintuitive.

Conclusion

Options 1, 2 and 3 all try to achieve the same thing. Option 1 is less powerful than option 2 but it is shorter so both have some justification for existing. Option 3 is less powerful than both while not being shorter than any of them. Option 4 is not commonly useful. Option 3 and 4 clash syntax-wise.

For all of the reasons above this RFC proposes to deprecate option 3 and 4 in PHP 8.1 and remove them in PHP 9.

Future scope

Options 1 and 2 are not perfect either. They only allow simple expressions on variables. A different RFC might propose to allow embedding arbitrary expressions into strings.

var_dump($"#{func()}")

If we decide to do that it would make sense to remove the less useful options first to not further add to the confusion, that's what this RFC is trying to achieve.

Vote

Voting starts 2021-xx-x and ends 2021-xx-xx.

As this is a language change, a 2/3 majority is required.

Deprecate ${} string interpolation in PHP 8.1 and remove them in PHP 9.0?
Real name Yes No
Final result: 0 0
This poll has been closed.
rfc/deprecate_dollar_brace_string_interpolation.1615645813.txt.gz · Last modified: 2021/03/13 14:30 by ilutov