PHP allows both square brackets and curly braces to be used interchangeably for accessing array elements and string offsets. For example:
$array = [1, 2]; echo $array[1]; // prints 2 echo $array{1}; // also prints 2 $string = "foo"; echo $string[0]; // prints "f" echo $string{0}; // also prints "f"
However, supporting both of these syntaxes can be confusing. Are there circumstances where one syntax behaves differently than the other? Is there a difference in performance between them? Is there some difference in scoping, since curly braces are the standard way to separate scope? What's the purpose of the curly brace syntax?
Apart from two short notes in the PHP Manual, the curly brace syntax is virtually undocumented. Furthermore, it has reduced functionality compared to the normal bracket syntax. For example, it cannot be used for pushing an element into an array:
$array[] = 3; echo $array[2]; // prints 3 $array{} = 3; // Parse error: syntax error, unexpected '}'
Nor can it be used to create an array:
$array = [1, 2]; // works $array = {1, 2}; // Parse error: syntax error, unexpected '{'
It can't be used for list assignment, either:
[$one, $two] = $array; // works {$one, $two} = $array; // Parse error: syntax error, unexpected ','
Deprecate curly brace syntax for accessing array elements and string offsets.
$arr = [1, 2, 3]; var_dump($arr{1});
Output:
Deprecated: Array and string offset access syntax with curly braces is deprecated in test.php line 3 int(2)
According to an internals discussion from June 2008 (see references
below), the curly brace syntax was deprecated in PHP 5.1 RC5, but the
deprecation warning was removed before the final release. In August
2006, the documentation for $str{42}
read “deprecated as of PHP 6”,
but again the deprecation never made it into a production release.
It has been suggested that the duplicate syntax is useful for differentiating
string and array offset access. The problem with this is that no distinction
is enforced by the language. Both syntaxes can be used for both arrays and
strings, so while one codebase might always use $str[0]
for strings and
$arr{0}
for arrays, another codebase might use the opposite convention,
which leads to more confusion rather than less.
To make sure that code is indexing a string and not an array, a type check should be used instead of relying on syntax that can be used for both strings and arrays (and thus doesn't tell you anything about the underlying type).
Nikita Popov checked the top 2k Composer packages, and found ~2.2k individual uses of the curly brace array syntax. Compared to the 888.3k total array accesses in the data set, usage of the alternative syntax is about 0.25%. However, even this number is inflated somewhat due to duplicate packages (for example, there are two packages that mirror the WordPress Core repository, each with 182 usages). 92% of usages in the top 2k packages are in just 25 unique projects.
A migration script has been implemented alongside the deprecation patch: https://gist.github.com/theodorejb/763b83a43522b0fc1755a537663b1863
A deprecation warning will be output when using the curly brace syntax to access array or string offsets.
Started 3 July 2019. Ends 17th July 2019
Remove the feature entirely (replacing the deprecation warning with a compiler error) in PHP 8 or another future release.
Current discussion: https://externals.io/message/104744 and https://externals.io/message/106130.
Discussion about deprecation in June 2008: https://externals.io/message/38153.
Discussion about deprecation in November 2005: https://externals.io/message/20143.