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 (``).
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;
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:
$ will potentially alter its behavior and require escaping of other parts of the string (similar to switching from ' to “)”, 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.
None
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.