Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions spec/10-expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,17 @@ isset($v1, $v2, $v3); // results in FALSE
list ( <i>list-expression-list<sub>opt</sub></i> )

<i>list-expression-list:</i>
<i>unkeyed-list-expression-list</i>
<i>keyed-list-expression-list</i> ,<sub>opt</sub>

<i>unkeyed-list-expression-list:</i>
<i>list-or-variable</i>
,
<i>list-expression-list</i> , <i>list-or-variable<sub>opt</sub></i>
<i>unkeyed-list-expression-list</i> , <i>list-or-variable<sub>opt</sub></ii>

<i>keyed-list-expression-list:</i>
<i>expression</i> => <i>list-or-variable</i>
<i>keyed-list-expression-list</i> , <i>expression</i> => <i>list-or-variable</i>

<i>list-or-variable:</i>
<i>list-intrinsic</i>
Expand Down Expand Up @@ -446,7 +454,8 @@ target variables. On success, it returns a copy of the source array. If the
source array is not an array or object implementing `ArrayAccess` no
assignments are performed and the return value is `NULL`.

All elements in the source array having keys of type `string` are ignored.
For *unkeyed-list-expression-list*, all elements in the source array having
keys of type `string` are ignored.
The element having an `int` key of 0 is assigned to the first target
variable, the element having an `int` key of 1 is assigned to the second
target variable, and so on, until all target variables have been
Expand All @@ -455,6 +464,15 @@ fewer source array elements having int keys than there are target
variables, the unassigned target variables are set to `NULL` and
a non-fatal error is produced.

For *keyed-list-expression-list*, each key-variable pair is handled in turn,
with the key and variable being separated by the `=>` symbol.
The element having the first key, with the key having been converted using the
same rules as the [subscript operator](10-expressions.md#subscript-operator),
is assigned to the frst target variable. This process is repeated for the
second `=>` pair, if any, and so on. Any other array elements are ignored.
If there is no array element with a given key, the unassigned target variable
is set to `NULL` and a non-fatal error is produced.

The assignments must occur in this order.

Any target variable may be a list, in which case, the corresponding
Expand All @@ -481,6 +499,24 @@ list($arr[1], $arr[0]) = [0, 1];
// $arr is [1 => 0, 0 => 1], in this order
list($arr2[], $arr2[]) = [0, 1];
// $arr2 is [0, 1]

list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2];
// $one is 1, $two is 2
list(
"one" => $one,
"two" => $two,
) = [
"one" => 1,
"two" => 2,
];
// $one is 1, $two is 2
list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [
["x" => 1, "y" => 2],
["x" => 3, "y" => 4]
];
// $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4
list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]];
// $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4
```

####print
Expand Down
10 changes: 9 additions & 1 deletion spec/19-grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,17 @@ The grammar notation is described in [Grammars section](09-lexical-structure.md#
list ( <i>list-expression-list<sub>opt</sub></i> )

<i>list-expression-list:</i>
<i>unkeyed-list-expression-list</i>
<i>keyed-list-expression-list</i> ,<sub>opt</sub>

<i>unkeyed-list-expression-list:</i>
<i>list-or-variable</i>
,
<i>list-expression-list</i> , <i>list-or-variable<sub>opt</sub></i>
<i>unkeyed-list-expression-list</i> , <i>list-or-variable<sub>opt</sub></i>

<i>keyed-list-expression-list:</i>
<i>expression</i> => <i>list-or-variable</i>
<i>keyed-list-expression-list</i> , <i>expression</i> => <i>list-or-variable</i>

<i>list-or-variable:</i>
<i>list-intrinsic</i>
Expand Down
14 changes: 14 additions & 0 deletions tests/expressions/list/list_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
"Nested" list()
--FILE--
<?php

list($a, list($b)) = array(new stdclass, array(new stdclass));
var_dump($a, $b);

?>
--EXPECT--
object(stdClass)#1 (0) {
}
object(stdClass)#2 (0) {
}
20 changes: 20 additions & 0 deletions tests/expressions/list/list_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Testing full-reference on list()
--FILE--
<?php

error_reporting(E_ALL);

$a = new stdclass;
$b =& $a;

list($a, list($b)) = array($a, array($b));
var_dump($a, $b, $a === $b);

?>
--EXPECT--
object(stdClass)#1 (0) {
}
object(stdClass)#1 (0) {
}
bool(true)
24 changes: 24 additions & 0 deletions tests/expressions/list/list_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
list() with non-array
--FILE--
<?php

list($a) = NULL;

list($b) = 1;

list($c) = 1.;

list($d) = 'foo';

list($e) = print '';

var_dump($a, $b, $c, $d, $e);

?>
--EXPECT--
NULL
NULL
NULL
NULL
NULL
21 changes: 21 additions & 0 deletions tests/expressions/list/list_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
list() with array reference
--FILE--
<?php

$arr = array(2, 1);
$b =& $arr;

list(,$a) = $b;

var_dump($a, $b);

?>
--EXPECT--
int(1)
array(2) {
[0]=>
int(2)
[1]=>
int(1)
}
50 changes: 50 additions & 0 deletions tests/expressions/list/list_005.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
Testing list() with several variables
--FILE--
<?php

$str = "foo";

list($a, $b, $c) = $str;

var_dump($a, $b, $c);

print "----\n";

$int = 1;

list($a, $b, $c) = $int;

var_dump($a, $b, $c);

print "----\n";

$obj = new stdClass;

list($a, $b, $c) = $obj;

var_dump($a, $b, $c);

print "----\n";

$arr = array(1, 2, 3);

list($a, $b, $c) = $arr;

var_dump($a, $b, $c);

?>
--EXPECTF--
NULL
NULL
NULL
----
NULL
NULL
NULL
----

Fatal error: Uncaught Error: Cannot use object of type stdClass as array in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d
12 changes: 12 additions & 0 deletions tests/expressions/list/list_006.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Testing nested list() with empty array
--FILE--
<?php

list($a, list($b, list(list($d)))) = array();

?>
--EXPECTF--
Notice: Undefined offset: 0 in %s on line %d

Notice: Undefined offset: 1 in %s on line %d
15 changes: 15 additions & 0 deletions tests/expressions/list/list_007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
Using lambda with list()
--FILE--
<?php

list($x, $y) = function() { };

var_dump($x, $y);

?>
--EXPECTF--
Fatal error: Uncaught Error: Cannot use object of type Closure as array in %slist_007.php:3
Stack trace:
#0 {main}
thrown in %slist_007.php on line 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
list() can be used to destructure to string offsets, __set and ArrayAccess::offsetSet
--FILE--
<?php

class Obj {
public $values = [];
public function __set($name, $value) {
$this->values[$name] = $value;
}
}

class Arr implements ArrayAccess {
public $values = [];
public function offsetSet($name, $value) {
$this->values[$name] = $value;
}
public function offsetGet($name) {}
public function offsetExists($name) {}
public function offsetUnset($name) {}
}

$str = 'ab';
list($str[0], $str[1]) = ['x', 'y'];
var_dump($str);

$obj = new Obj;
list($obj->foo, $obj->bar) = ['foo', 'bar'];
var_dump($obj->values);

$arr = new Arr;
list($arr['foo'], $arr['bar']) = ['foo', 'bar'];
var_dump($arr->values);

?>
--EXPECT--
string(2) "xy"
array(2) {
["foo"]=>
string(3) "foo"
["bar"]=>
string(3) "bar"
}
array(2) {
["foo"]=>
string(3) "foo"
["bar"]=>
string(3) "bar"
}
10 changes: 10 additions & 0 deletions tests/expressions/list/list_empty_error.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--TEST--
Empty list() assignments are not allowed
--FILE--
<?php

list(,,,,,,,,,,) = [];

?>
--EXPECTF--
Fatal error: Cannot use empty list in %s on line %d
71 changes: 71 additions & 0 deletions tests/expressions/list/list_keyed.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
--TEST--
list() with keys
--FILE--
<?php

$antonyms = [
"good" => "bad",
"happy" => "sad",
];

list("good" => $good_antonym, "happy" => $happy_antonym) = $antonyms;
var_dump($good_antonym, $happy_antonym);

echo PHP_EOL;

$powersOfTwo = [
1 => 2,
2 => 4,
3 => 8
];

list(1 => $two_1, 2 => $two_2, 3 => $two_3) = $powersOfTwo;
var_dump($two_1, $two_2, $two_3);

echo PHP_EOL;

$contrivedMixedKeyTypesExample = [
7 => "the best PHP version",
"elePHPant" => "the cutest mascot"
];

list(7 => $seven, "elePHPant" => $elePHPant) = $contrivedMixedKeyTypesExample;
var_dump($seven, $elePHPant);

echo PHP_EOL;

$allTogetherNow = [
"antonyms" => $antonyms,
"powersOfTwo" => $powersOfTwo,
"contrivedMixedKeyTypesExample" => $contrivedMixedKeyTypesExample
];

list(
"antonyms" => list("good" => $good_antonym, "happy" => $happy_antonym),
"powersOfTwo" => list(1 => $two_1, 2 => $two_2, 3 => $two_3),
"contrivedMixedKeyTypesExample" => list(7 => $seven, "elePHPant" => $elePHPant)
) = $allTogetherNow;

var_dump($good_antonym, $happy_antonym);
var_dump($two_1, $two_2, $two_3);
var_dump($seven, $elePHPant);

?>
--EXPECT--
string(3) "bad"
string(3) "sad"

int(2)
int(4)
int(8)

string(20) "the best PHP version"
string(17) "the cutest mascot"

string(3) "bad"
string(3) "sad"
int(2)
int(4)
int(8)
string(20) "the best PHP version"
string(17) "the cutest mascot"
Loading