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