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