diff --git a/appendices/tokens.xml b/appendices/tokens.xml
index dfe206d1ade8..5b283399c0a2 100644
--- a/appendices/tokens.xml
+++ b/appendices/tokens.xml
@@ -204,8 +204,10 @@ defined('T_FN') || define('T_FN', 10001);
T_CURLY_OPEN{$
- complex
- variable parsed syntax
+
+ advanced
+ variable string interpolation
+ T_DEC
@@ -255,8 +257,10 @@ defined('T_FN') || define('T_FN', 10001);
T_DOLLAR_OPEN_CURLY_BRACES${
- complex
- variable parsed syntax
+
+ basic
+ variable string interpolation
+ T_DOUBLE_ARROW
@@ -799,8 +803,10 @@ defined('T_FN') || define('T_FN', 10001);
T_STRING_VARNAME"${a
- complex
- variable parsed syntax
+
+ variable variables
+ to interpolate in a string
+ T_SWITCH
diff --git a/language/types/string.xml b/language/types/string.xml
index 53c4c356b310..f4955a7a1d28 100644
--- a/language/types/string.xml
+++ b/language/types/string.xml
@@ -199,7 +199,7 @@ echo 'Variables do not $expand $either';
The most important feature of double-quoted strings is the fact
that variable names will be expanded. See
- string parsing for
+ string interpolation for
details.
@@ -592,7 +592,7 @@ FOOBAR;
Nowdocs are to single-quoted strings what heredocs are to double-quoted
strings. A nowdoc is specified similarly to a heredoc, but no
- parsing is done inside a nowdoc. The construct is ideal for
+ String interpolation is done inside a nowdoc. The construct is ideal for
embedding PHP code or other large blocks of text without the need for
escaping. It shares some features in common with the SGML
<![CDATA[ ]]> construct, in that it declares a
@@ -684,37 +684,29 @@ EOT;
- Variable parsing
+ String interpolation
When a string is specified in double quotes or with heredoc,
- variables are parsed within it.
+ variables can be substituted within it.
There are two types of syntax: a
- simple one and a
- complex one.
- The simple syntax is the most common and convenient. It provides a way to
+ basic one and an
+ advanced one.
+ The basic syntax is the most common and convenient. It provides a way to
embed a variable, an array value, or an object
property in a string with a minimum of effort.
-
- The complex syntax can be recognised by the
- curly braces surrounding the expression.
-
-
-
- Simple syntax
-
+
+ Basic syntax
- If a dollar sign ($) is encountered, the parser will
- greedily take as many tokens as possible to form a valid variable name.
- Enclose the variable name in curly braces to explicitly specify the end of
- the name.
+ If a dollar sign ($) is encountered, the characters
+ that follow it which can be used in a variable name will be interpreted
+ as such and substituted.
-
]]>
@@ -736,43 +722,131 @@ echo "He drank some juice made of {$juice}s.";
- Similarly, an array index or an object property
- can be parsed. With array indices, the closing square bracket
- (]) marks the end of the index. The same rules apply to
- object properties as to simple variables.
+ Formally, the structure for the basic variable substitution syntax is
+ as follows:
+
+
+Simple syntax example
-
+offset-or-property::
+ offset-in-string
+ | property-in-string
+
+offset-in-string::
+ [ name ]
+ | [ variable-name ]
+ | [ integer-literal ]
+
+property-in-string::
+ -> name
+
+variable-name::
+ $ name
+
+name::
+ [a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*
+
+]]>
+
+
+
+
+
+ The ${ expression } syntax is deprecated as of
+ PHP 8.2.0, as it can be interpreted as
+ variable variables:
+
+
"purple");
+const foo = 'bar';
+$foo = 'foo';
+$bar = 'bar';
+var_dump("${foo}");
+var_dump("${(foo)}");
+?>
+]]>
+
+ &example.outputs.82;
+
+
+
+ &example.outputs;
+
+
+
+
+ The advanced
+ string interpolation syntax should be used instead.
+
+
+
+
+
+ If it is not possible to form a valid name the dollar sign remains
+ as verbatim in the string:
+
+
+
+
+]]>
+
+ &example.outputs;
+
+
+
+
+
-echo "He drank some $juices[0] juice.".PHP_EOL;
-echo "He drank some $juices[1] juice.".PHP_EOL;
-echo "He drank some $juices[koolaid1] juice.".PHP_EOL;
+
+ Interpolating the value of the first dimension of an array or property
+
+ "purple");
-class people {
- public $john = "John Smith";
- public $jane = "Jane Smith";
- public $robert = "Robert Paulsen";
+echo "He drank some $juices[0] juice.";
+echo PHP_EOL;
+echo "He drank some $juices[1] juice.";
+echo PHP_EOL;
+echo "He drank some $juices[string_key] juice.";
+echo PHP_EOL;
- public $smith = "Smith";
+class A {
+ public $s = "string";
}
-$people = new people();
+$o = new A();
-echo "$people->john drank some $juices[0] juice.".PHP_EOL;
-echo "$people->john then said hello to $people->jane.".PHP_EOL;
-echo "$people->john's wife greeted $people->robert.".PHP_EOL;
-echo "$people->robert greeted the two $people->smiths."; // Won't work
+echo "Object value: $o->s.";
?>
]]>
@@ -782,14 +856,20 @@ echo "$people->robert greeted the two $people->smiths."; // Won't work
He drank some apple juice.
He drank some orange juice.
He drank some purple juice.
-John Smith drank some apple juice.
-John Smith then said hello to Jane Smith.
-John Smith's wife greeted Robert Paulsen.
-Robert Paulsen greeted the two .
+Object value: string.
]]>
+
+
+ The array key must be unquoted, and it is therefore not possible to
+ refer to a constant as a key with the basic syntax. Use the
+ advanced
+ syntax instead.
+
+
+
As of PHP 7.1.0 also negative numeric indices are
supported.
@@ -816,20 +896,23 @@ Changing the character at index -3 to o gives strong.
- For anything more complex, you should use the complex syntax.
+ For anything more complex, the
+ advanced
+ syntax must be used.
-
- Complex (curly) syntax
+
+ Advanced (curly) syntax
- This isn't called complex because the syntax is complex, but because it
- allows for the use of complex expressions.
+ The advanced syntax permits the interpolation of
+ variables with arbitrary accessors.
- Any scalar variable, array element or object property with a
+ Any scalar variable, array element or object property
+ (static or not) with a
string representation can be included via this syntax.
The expression is written the same way as it would appear outside the
string, and then wrapped in { and
@@ -843,10 +926,18 @@ Changing the character at index -3 to o gives strong.
'Indexed value',
+ 'const-key' => 'Key with minus sign',
+ 'foo' => ['foo1', 'foo2', 'foo3']
+];
// Won't work, outputs: This is { fantastic}
echo "This is { $great}";
@@ -854,8 +945,16 @@ echo "This is { $great}";
// Works, outputs: This is fantastic
echo "This is {$great}";
+class Square {
+ public $width;
+
+ public function __construct(int $width) { $this->width = $width; }
+}
+
+$square = new Square(5);
+
// Works
-echo "This square is {$square->width}00 centimeters broad.";
+echo "This square is {$square->width}00 centimeters wide.";
// Works, quoted keys only work using the curly brace syntax
@@ -865,29 +964,15 @@ echo "This works: {$arr['key']}";
// Works
echo "This works: {$arr[4][3]}";
-// This is wrong for the same reason as $foo[bar] is wrong outside a string.
-// PHP first looks for a constant named foo, and throws an error if not found.
-// If the constant is found, its value (and not 'foo' itself) would be used
-// for the array index.
-echo "This is wrong: {$arr[foo][3]}";
+echo "This works: {$arr[DATA_KEY]}";
-// Works. When using multi-dimensional arrays, always use braces around arrays
+// When using multidimensional arrays, always use braces around arrays
// when inside of strings
echo "This works: {$arr['foo'][3]}";
-// Works.
-echo "This works: " . $arr['foo'][3];
-
-echo "This works too: {$obj->values[3]->name}";
-
-echo "This is the value of the var named $name: {${$name}}";
+echo "This works: {$obj->values[3]->name}";
-echo "This is the value of the var named by the return value of getName(): {${getName()}}";
-
-echo "This is the value of the var named by the return value of \$object->getName(): {${$object->getName()}}";
-
-// Won't work, outputs: This is the return value of getName(): {getName()}
-echo "This is the return value of getName(): {getName()}";
+echo "This works: {$obj->$staticProp}";
// Won't work, outputs: C:\folder\{fantastic}.txt
echo "C:\folder\{$great}.txt"
@@ -895,82 +980,16 @@ echo "C:\folder\{$great}.txt"
echo "C:\\folder\\{$great}.txt"
?>
]]>
-
-
- It is also possible to access class properties using variables
- within strings using this syntax.
-
-
-
-
-$bar}\n";
-echo "{$foo->{$baz[1]}}\n";
-?>
-]]>
-
- &example.outputs;
-
-
-
-
-
-
- The value accessed from functions, method calls, static class variables,
- and class constants inside
- {$} will be interpreted as the name
- of a variable in the scope in which the string is defined. Using
- single curly braces ({}) will not work for
- accessing the return values of functions or methods or the
- values of class constants or static class variables.
-
+
+ As this syntax allows arbitrary expressions it is possible to use
+ variable variables
+ within the advanced syntax.
+
-
-
-
-
-]]>
-
-
-