reeze

Reeze Xia

Contents

PHP RFC: Default Value in List Assignment Syntax

Introduction

We could destruct variables from an array with list constuct, it may be nested or a simple array. But there is no guarantee that the array can fulfill all variables, it will be simple assigned with null with notice error (not good). We will need several redundant code to handle the possible cases if we want to check it and assign it with default values.

For the similar reason we introduced Null coalesce "??" and Ternary Operator "?:" to help write clean code.

Some clever users figured out some workaround like this User contributed notes. But that is not good enough and ugly.

Proposal

Support new syntax to set default values for list elements, when the requested index it is not found in array:

// basic syntax
list($a, $b='default') = [1];      // a = 1, b = 'default'
list($a, $b='default') = [1, 2];  // a = 1, b = 2
 
//  comparation 
list($a, list($b=1, $c=2)) = $arr;
// or we need to check it ourself
if (!isset($arr[1][0])) {
    $arr[1][0] = 1;
}
if (!isset($arr[1][1])) {
    $arr[1][0] = 2;
}
 
list($a, list($b, $c)) = $arr;
 
 
// other examples
function say_hello()
{
    return "Hello";
}
$name = 'PHP';
list($a=say_hello(), $b=$name."7.0") = []; // a = 'Hello', b = 'PHP7.0'
 
list($a, list($b=1, $c=2)) = [1]; // a = 1, b = 1, c = 2

The assignment could be considered as a shortcut for:

list($a, $b='default') = $arr;
 
// equals
 
$a = $arr[0];
$b = isset($arr[1]) ? $arr[1] : 'default';

This seems not a lot of work than the new syntax. But sometimes we need to destruct nested array and there are morn than two variables, anyway list() itself is designed to avoid assign by hand for short and clean code.

The syntax is:

assignment_list_element:
		variable				
+	|	variable '=' expr # the new syntax. value could be any expression
	|	T_LIST '(' assignment_list ')'
	|	/* empty */				

The syntax is same as function's default value for parameters.

We could also set default value in foreach list context:

foreach($arr as list($k, list($v1='deafult', $v2='default2'))) {
    // do something
}

More case could be found from PR's tests: https://github.com/php/php-src/pull/1623/files

This feature could also be found in Clojure and Javascript for destructing.

Backward Incompatible Changes

No BC break.

Proposed PHP Version(s)

PHP 7.1

RFC Impact

To Opcache

I am working on opcache compatibility.

Open Issues

None for now

Future Scope

Proposed Voting Choices

* Whether accept the RFC for PHP 7.1

This project requires a 2/3 majority (see voting)

Patches and Tests

* Patch: https://github.com/php/php-src/pull/1623

I am working on opcache compatibility

Implementation

After the project 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

Versions

Version Changed Date
0.1 Initial version