====== PHP RFC: Arbitrary string interpolation ====== * Date: 2022-03-17 * Author: Ilija Tovilo, tovilo.ilija@gmail.com * Status: Withdrawn * Target Version: PHP 8.2 * Implementation: https://github.com/php/php-src/pull/8256 ===== 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 [[https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation|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 "{$: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 (''<< echo << ===== 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 ===== 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 ^ | [[https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated|C#]] | ''$"x + y = {x + y}"'' | | [[https://api.dart.dev/stable/2.16.1/dart-core/String-class.html|Dart]] | '''x + y = ${x + y}''' | | [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals|JavaScript]] | ''`x + y = ${x + y}`'' | | [[https://kotlinlang.org/docs/basic-types.html#string-templates|Kotlin]] | ''"x + y = ${x + y}"'' | | [[https://peps.python.org/pep-0498/|Python]] | ''f'x + y = {x + y}''' | | [[https://docs.raku.org/language/quoting.html#Interpolation:_qq|Raku (Perl6)]] | ''"\$x + \$y = { $x + $y }"'' | | [[http://ruby-for-beginners.rubymonstas.org/bonus/string_interpolation.html|Ruby]] | ''"x + y = #{x + y}"'' | | [[https://docs.scala-lang.org/overviews/core/string-interpolation.html|Scala]] | ''s"x + y = ${$x + $y}"'' | | [[https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#ID292|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. * Yes * No