Table of Contents

PHP RFC: Arbitrary string interpolation

Proposal

PHP has four types of string interpolation. The two most common forms are “$foo” and “{$foo}”. For details on the two other forms of string interpolation see the deprecate ${} string interpolation RFC.

All the current forms of string interpolation are limited to variables or variable chains (array access, properties, method calls, etc). This probably covers 80% of use cases for string interpolation (unverified figure). However, there are times when this is not enough, namely you might want to embed any of the following in your string:

$world = 'world';
echo "Hello {strtoupper($world)}!";
// Hello {strtoupper(world)}
// :(

This RFC proposes to add a new form for string interpolation that works for arbitrary expressions.

$world = 'world';
echo "Hello {$:strtoupper($world)}!";
// Hello WORLD!
// :)
 
echo "{$:T_PAAMAYIM_NEKUDOTAYIM}";
echo "{$:Foo::class}";
echo "{$:self::doSomething()}";

The proposed syntax works in all cases where existing string interpolation is allowed, namely double quoted strings (“”), heredoc (<<<TXT TXT) and the execution operator (``).

Motivation

Of course, this can already be achieved in two other ways:

Creating local variables is not a terrible option. It does pollute the variable symbol table a bit and it requires more visual jumping to see what value is being embedded.

Concatenation is a fair bit worse. The quotes and . symbols lead to a symbol soup, and the approach will not work nicely with heredoc at all.

echo <<<TXT
    Hello 
TXT /* <-- Must be on a new line */ . strtoupper('world') . <<<TXT
TXT;

Syntax choice

The primary advantage of the syntax “{$:expr}” is that is it is fully backwards compatible as it leads to a syntax error in PHP 8.1 rather than being interpreted literally. It also looks familiar while being distinctly different from other forms of string interpolation to avoid confusion. The : could be swapped with another character or even white space, but I believe that white space has a bigger chance of leading to confusion.

A different syntax could be chosen with a given BC break.

echo "Hello #{strtoupper('world')}";

This could be mitigated by adding a prefix to the string itself.

echo $"Hello #{strtoupper('world')}";

I think this is unfortunate because:

Escaping

Escaping works by adding a backslash \ after the brace {.

echo "{\$:foo}";
// {$:foo}

If you're thinking why not before the {, PHPs existing escaping of \{$foo} could be considered buggy. While it escapes the {}, it also gets printed itself.

$foo = 'bar';
echo "\{$foo}";
// \{bar}

https://3v4l.org/oEWFC

That said, escaping the proposed string interpolation {$: should be very rare in practice.

Backwards incompatible changes

None

Comparison to other languages

Most modern languages have string interpolation that allow arbitrary expressions.

Language Syntax
C# $“x + y = {x + y}”
Dart 'x + y = ${x + y}'
JavaScript `x + y = ${x + y}`
Kotlin “x + y = ${x + y}”
Python f'x + y = {x + y}'
Raku (Perl6) “\$x + \$y = { $x + $y }”
Ruby “x + y = #{x + y}”
Scala s“x + y = ${$x + $y}”
Swift “x + y = \(x + y)”

Credits

Credits to Rowan Tommins (IMSoP) for the syntax suggestion and comparison to other languges.

Vote

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

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

Accept arbitrary string interpolation in PHP 8.2?
Real name Yes No
Final result: 0 0
This poll has been closed.