rfc:bare_name_array_literal

PHP RFC: Bare Name Array Literal

Introduction

At present, arrays are a tad cumbersome to define. String keys must be quoted and followed by a double arrow, then the element ends with a comma:

$myArray = [
    "stringKey" => 3,
    "otherKey" => true,
    "foobar" => [
        "anotherKey" => false,
        "andSoOn" => [
            "moreKeys" => "thing"
        ]
    ],
    "key with spaces" => "boo"
];

This adds up to a total of 5 characters that must be typed, 7 including spaces. However, in JavaScript, you do not need to quote key names if they fit the profile of a normal identifier (no spaces, doesn't begin with a digit, no dashes, etc.), making objects very convenient to define:

var myArray = {
    stringKey: 3,
    otherKey: true,
    foobar: {
        anotherKey: false,
        andSoOn: {
            moreKeys: thing
        }
    },
    "key with spaces": "boo"
};

This means only 3 characters must be typed (4 including spaces) for the most common case, which is far more convenient. Hence, this RFC proposes an optional similar syntax for PHP, where keys do not need to be quoted when they are followed by a colon instead of a double arrow, so long as they fit the profile of IS_STRING:

$myArray = [
    stringKey: 3,
    otherKey: true,
    foobar: [
        anotherKey: false,
        andSoOn: [
            moreKeys: thing
        ]
    ],
    "key with spaces" => "boo"
];

This means that only 2 characters need to be typed (3 with spaces) for most key names. It makes defining arrays with string keys more convenient and it's easier to read (especially if you have an IDE which syntax highlights strings).

A secondary benefit is to the Named Parameters RFC in that it would provide a clear syntax choice consistent with arrays and the same as C# and Objective-C, i.e.:

$array = [true, 3, foo: 'bar', "foo bar" => 7];
call_user_func_array('quxbang', $array);
// is the same as:
quxbang(...$array):
// is the same as:
quxbang(true, 3, foo: 'bar', "foo bar" => 7);

Symmetry between arrays and named parameters would be desirable as otherwise it could cause confusion. This RFC would ensure it.

Even without named parameters, this makes it nicer to use functions which take an array of options. For example:

$ctx = stream_context_create([http: [method: "GET", header: "Accept-language: en", user_agent: 'Foo-Bot', protocol_version: 1.1]]);
 
// or
 
$hash = password_hash($_POST['pwd'], PASSWORD_BCRYPT, [salt: $secure_salt, cost: 25]);

This makes creating JSON more convenient, too:

// Real example
$ws->send(json_encode([
    type: 'join',
    room: $player->currentRoom,
    nick: $player->curretName,
    x: 0,
    y: 0,
    avatar: 'foo.png'
]));

This complements the Bare Name Array Dereference RFC, as both this proposal and that one deal with using bare T_STRING names for array keys.

Proposal

Along with the existing syntax for specifying a key-value pair in an array literal, the following new syntax is added:

  T_STRING ":" value

This functions the same as a quoted key followed by the double arrow.

This does not affect using constants with the double arrow syntax, and the following code would still result in an array mapping 'bar' to 3:

const('foo', 'bar');
$arr = [foo => 3];
// array(1) {
//   ["bar"]=>
//   int(3)
// }

By contrast, constants do not affect the colon syntax, and the following code would result in an array mapping 'foo' to 3:

const foo = 'bar';
$arr = [foo: 3];
// array(1) {
//   ["foo"]=>
//   int(3)
// }

The colon and double arrow syntaxes can be mixed if desired:

$arr = [
    foo: 3,
    0 => 'bar'
];

Backward Incompatible Changes

None. This will not affect existing code. => will continue to resolve constants. : will not.

Proposed PHP Version(s)

Proposed for the next PHP 5.x, which at the time of writing, is PHP 5.7.

RFC Impact

SAPIs, extensions, opcache, constants and php.ini are unaffected. No new opcodes are added, this is purely a parsing change.

As aforementioned, it would give a better syntax for the Named Parameters RFC.

Open Issues

None.

Unaffected PHP Functionality

Arrays still work the same as ever. [“foobar” => 3] and [foobar: 3] are exactly the same. It is completely optional and doesn't break anything.

Future Scope

Object literals might be a nice-to-have, but then again (object)[foobar: 3] would work just as well.

Vote

A 2/3 majority as it is a language change. Voting began on 2014-06-21 (after a hiccup it was restarted) and ended 2014-06-28.

Merge bare name array literal into master/PHP 5.7?
Real name Yes No
aharvey (aharvey)  
ajf (ajf)  
arpad (arpad)  
brianlmoon (brianlmoon)  
bwoebi (bwoebi)  
colder (colder)  
datibbaw (datibbaw)  
derick (derick)  
levim (levim)  
malukenho (malukenho)  
marco (marco)  
mbeccati (mbeccati)  
rasmus (rasmus)  
stas (stas)  
thekid (thekid)  
tyrael (tyrael)  
zeev (zeev)  
Final result: 3 14
This poll has been closed.

Patches and Tests

There is a working and tested patch implementing this here: https://github.com/TazeTSchnitzel/php-src/compare/bareNameArrayLiteral

The branch on my GitHub account is here: https://github.com/TazeTSchnitzel/php-src/tree/bareNameArrayLiteral

Implementation

If/when the RFC is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

None as yet.

rfc/bare_name_array_literal.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1