rfc:deprecate_curly_braces_array_access

PHP RFC: Deprecate curly brace syntax for accessing array elements and string offsets

Introduction

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 ','

Proposal

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)

Discussion

Wasn't the curly brace syntax deprecated once before?

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.

Is the curly brace syntax valuable for differentiating string and array offset access?

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).

How frequently is the curly brace syntax used?

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.

Will it be too much work for people to migrate code away from the curly brace syntax?

A migration script has been implemented alongside the deprecation patch: https://gist.github.com/theodorejb/763b83a43522b0fc1755a537663b1863

Backward Incompatible Changes

A deprecation warning will be output when using the curly brace syntax to access array or string offsets.

Vote

Started 3 July 2019. Ends 17th July 2019

Deprecate curly brace array and string offset syntax in PHP 7.4
Real name Yes No
aeoris (aeoris)  
ashnazg (ashnazg)  
brzuchal (brzuchal)  
bwoebi (bwoebi)  
carusogabriel (carusogabriel)  
cpriest (cpriest)  
daverandom (daverandom)  
derick (derick)  
dmitry (dmitry)  
duncan3dc (duncan3dc)  
galvao (galvao)  
gasolwu (gasolwu)  
girgias (girgias)  
jasny (jasny)  
jhdxr (jhdxr)  
kalle (kalle)  
kelunik (kelunik)  
kguest (kguest)  
kinncj (kinncj)  
levim (levim)  
mbeccati (mbeccati)  
mcmic (mcmic)  
mfonda (mfonda)  
mike (mike)  
nikic (nikic)  
ocramius (ocramius)  
peehaa (peehaa)  
petk (petk)  
pmjones (pmjones)  
pollita (pollita)  
ramsey (ramsey)  
reywob (reywob)  
rjhdby (rjhdby)  
rtheunissen (rtheunissen)  
salathe (salathe)  
santiagolizardo (santiagolizardo)  
sergey (sergey)  
stas (stas)  
subjective (subjective)  
svpernova09 (svpernova09)  
trowski (trowski)  
wjx (wjx)  
yunosh (yunosh)  
Final result: 37 6
This poll has been closed.

Future Scope

Remove the feature entirely (replacing the deprecation warning with a compiler error) in PHP 8 or another future release.

References

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.

rfc/deprecate_curly_braces_array_access.txt · Last modified: 2019/08/10 23:19 by derick