|
| 1 | +--TEST-- |
| 2 | +list() with keys, evaluation order |
| 3 | +--FILE-- |
| 4 | +<?php |
| 5 | + |
| 6 | +// list($a => $b, $c => $d) = $e; |
| 7 | +// Should be evaluated in the order: |
| 8 | +// 1. Evaluate $e |
| 9 | +// 2. Evaluate $a |
| 10 | +// 3. Evaluate $e[$a] |
| 11 | +// 4. Assign $b from $e[$a] |
| 12 | +// 5. Evaluate $c |
| 13 | +// 6. Evaluate $e[$c] |
| 14 | +// 7. Assign $c from $e[$a] |
| 15 | + |
| 16 | +// In order to observe this evaluation order, let's use some observer objects! |
| 17 | + |
| 18 | +class Stringable |
| 19 | +{ |
| 20 | + private $name; |
| 21 | + public function __construct(string $name) { |
| 22 | + $this->name = $name; |
| 23 | + } |
| 24 | + |
| 25 | + public function __toString(): string { |
| 26 | + echo "$this->name evaluated.", PHP_EOL; |
| 27 | + return $this->name; |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +class Indexable implements ArrayAccess |
| 32 | +{ |
| 33 | + public function offsetExists($offset): bool { |
| 34 | + echo "Existence of offset $offset checked for.", PHP_EOL; |
| 35 | + return true; |
| 36 | + } |
| 37 | + |
| 38 | + public function offsetUnset($offset): void { |
| 39 | + echo "Offset $offset removed.", PHP_EOL; |
| 40 | + } |
| 41 | + |
| 42 | + public function offsetGet($offset) { |
| 43 | + echo "Offset $offset retrieved.", PHP_EOL; |
| 44 | + return "value for offset $offset"; |
| 45 | + } |
| 46 | + |
| 47 | + public function offsetSet($offset, $value): void { |
| 48 | + echo "Offset $offset set to $value.", PHP_EOL; |
| 49 | + } |
| 50 | +} |
| 51 | + |
| 52 | +class IndexableRetrievable |
| 53 | +{ |
| 54 | + private $label; |
| 55 | + private $indexable; |
| 56 | + |
| 57 | + public function __construct(string $label, Indexable $indexable) { |
| 58 | + $this->label = $label; |
| 59 | + $this->indexable = $indexable; |
| 60 | + } |
| 61 | + |
| 62 | + public function getIndexable(): Indexable { |
| 63 | + echo "Indexable $this->label retrieved.", PHP_EOL; |
| 64 | + return $this->indexable; |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +$a = new Stringable("A"); |
| 69 | +$c = new Stringable("C"); |
| 70 | + |
| 71 | +$e = new IndexableRetrievable("E", new Indexable(["A" => "value for A", "C" => "value for C"])); |
| 72 | + |
| 73 | +$store = new Indexable; |
| 74 | + |
| 75 | +list((string)$a => $store["B"], (string)$c => $store["D"]) = $e->getIndexable(); |
| 76 | + |
| 77 | +?> |
| 78 | +--EXPECT-- |
| 79 | +Indexable E retrieved. |
| 80 | +A evaluated. |
| 81 | +Offset A retrieved. |
| 82 | +Offset B set to value for offset A. |
| 83 | +C evaluated. |
| 84 | +Offset C retrieved. |
| 85 | +Offset D set to value for offset C. |
0 commit comments