PHP RFC: Arbitrary string interpolation


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:

  • Function calls
  • Constants
  • Class constants
  • Static method calls
$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 "{$: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 (``).


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

  • By creating a temporary local variable
  • By stopping the string and concatenating the value with .

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
TXT /* <-- Must be on a new line */ . strtoupper('world') . <<<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:

  • Converting an existing string to $ will potentially alter its behavior and require escaping of other parts of the string (similar to switching from ' to )
  • The prefix will need to work for all existing string types that allow interpolation (, heredoc, execute operator), doubling the types of interpolated string we have


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}


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

Backwards incompatible changes


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 to Rowan Tommins (IMSoP) for the syntax suggestion and comparison to other languges.


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.
rfc/arbitrary_string_interpolation.txt · Last modified: 2022/06/25 21:47 by ilutov