rfc:arbitrary_string_interpolation

This is an old revision of the document!


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:

  • Function calls
  • Constants
  • Class constants
  • Statis 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 "{$:T_PAAMAYIM_NEKUDOTAYIM}";
echo "{$:Foo::class}";
echo "{$:self::doSomething()}";

The proposed syntax works in double quoted strings (“”), heredoc (<<<TXT TXT) and the execution operator (``)

Motivation

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

1. By creating a temporary local variable
2. 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
    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 whitespace, but I believe that whitespace 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 the behavior and require escaping 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)

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

Credits

Credits to Rowan Tommins (IMSoP) for the syntax suggestion.

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.
rfc/arbitrary_string_interpolation.1647544399.txt.gz · Last modified: 2022/03/17 19:13 by ilutov