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