1--TEST--
2ZE2 ArrayAccess and ArrayReferenceProxy with references
3--FILE--
4<?php
5
6// NOTE: This will become part of SPL
7
8class ArrayReferenceProxy implements ArrayAccess
9{
10    private $object;
11    private $element;
12
13    function __construct(ArrayAccess $object, array &$element)
14    {
15        echo __METHOD__ . "(Array)\n";
16        $this->object = $object;
17        $this->element = &$element;
18    }
19
20    function offsetExists($index): bool {
21        echo __METHOD__ . "($this->element, $index)\n";
22        return array_key_exists($index, $this->element);
23    }
24
25    function offsetGet($index): mixed {
26        echo __METHOD__ . "(Array, $index)\n";
27        return isset($this->element[$index]) ? $this->element[$index] : NULL;
28    }
29
30    function offsetSet($index, $value): void {
31        echo __METHOD__ . "(Array, $index, $value)\n";
32        $this->element[$index] = $value;
33    }
34
35    function offsetUnset($index): void {
36        echo __METHOD__ . "(Array, $index)\n";
37        unset($this->element[$index]);
38    }
39}
40
41class Peoples implements ArrayAccess
42{
43    public $person;
44
45    function __construct()
46    {
47        $this->person = array(array('name'=>'Foo'));
48    }
49
50    function offsetExists($index): bool
51    {
52        return array_key_exists($index, $this->person);
53    }
54
55    function offsetGet($index): mixed
56    {
57        return new ArrayReferenceProxy($this, $this->person[$index]);
58    }
59
60    function offsetSet($index, $value): void
61    {
62        $this->person[$index] = $value;
63    }
64
65    function offsetUnset($index): void
66    {
67        unset($this->person[$index]);
68    }
69}
70
71$people = new Peoples;
72
73var_dump($people->person[0]['name']);
74$people->person[0]['name'] = $people->person[0]['name'] . 'Bar';
75var_dump($people->person[0]['name']);
76$people->person[0]['name'] .= 'Baz';
77var_dump($people->person[0]['name']);
78
79echo "===ArrayOverloading===\n";
80
81$people = new Peoples;
82
83var_dump($people[0]);
84var_dump($people[0]['name']);
85$people[0]['name'] = 'FooBar';
86var_dump($people[0]['name']);
87$people[0]['name'] = $people->person[0]['name'] . 'Bar';
88var_dump($people[0]['name']);
89$people[0]['name'] .= 'Baz';
90var_dump($people[0]['name']);
91unset($people[0]['name']);
92var_dump($people[0]);
93var_dump($people[0]['name']);
94$people[0]['name'] = 'BlaBla';
95var_dump($people[0]['name']);
96
97?>
98--EXPECTF--
99string(3) "Foo"
100string(6) "FooBar"
101string(9) "FooBarBaz"
102===ArrayOverloading===
103ArrayReferenceProxy::__construct(Array)
104object(ArrayReferenceProxy)#%d (2) {
105  ["object":"ArrayReferenceProxy":private]=>
106  object(Peoples)#%d (1) {
107    ["person"]=>
108    array(1) {
109      [0]=>
110      &array(1) {
111        ["name"]=>
112        string(3) "Foo"
113      }
114    }
115  }
116  ["element":"ArrayReferenceProxy":private]=>
117  &array(1) {
118    ["name"]=>
119    string(3) "Foo"
120  }
121}
122ArrayReferenceProxy::__construct(Array)
123ArrayReferenceProxy::offsetGet(Array, name)
124string(3) "Foo"
125ArrayReferenceProxy::__construct(Array)
126ArrayReferenceProxy::offsetSet(Array, name, FooBar)
127ArrayReferenceProxy::__construct(Array)
128ArrayReferenceProxy::offsetGet(Array, name)
129string(6) "FooBar"
130ArrayReferenceProxy::__construct(Array)
131ArrayReferenceProxy::offsetSet(Array, name, FooBarBar)
132ArrayReferenceProxy::__construct(Array)
133ArrayReferenceProxy::offsetGet(Array, name)
134string(9) "FooBarBar"
135ArrayReferenceProxy::__construct(Array)
136ArrayReferenceProxy::offsetGet(Array, name)
137ArrayReferenceProxy::offsetSet(Array, name, FooBarBarBaz)
138ArrayReferenceProxy::__construct(Array)
139ArrayReferenceProxy::offsetGet(Array, name)
140string(12) "FooBarBarBaz"
141ArrayReferenceProxy::__construct(Array)
142ArrayReferenceProxy::offsetUnset(Array, name)
143ArrayReferenceProxy::__construct(Array)
144object(ArrayReferenceProxy)#%d (2) {
145  ["object":"ArrayReferenceProxy":private]=>
146  object(Peoples)#%d (1) {
147    ["person"]=>
148    array(1) {
149      [0]=>
150      &array(0) {
151      }
152    }
153  }
154  ["element":"ArrayReferenceProxy":private]=>
155  &array(0) {
156  }
157}
158ArrayReferenceProxy::__construct(Array)
159ArrayReferenceProxy::offsetGet(Array, name)
160NULL
161ArrayReferenceProxy::__construct(Array)
162ArrayReferenceProxy::offsetSet(Array, name, BlaBla)
163ArrayReferenceProxy::__construct(Array)
164ArrayReferenceProxy::offsetGet(Array, name)
165string(6) "BlaBla"
166