1--TEST--
2SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject ARE invoked when manipulating its elements using ->.
3--FILE--
4<?php
5class C {
6    public $a = 1;
7    public $b = 2;
8    public $c = 3;
9
10    private $priv = 'secret';
11}
12
13class UsesMagic extends ArrayObject {
14
15    public $b = "This should appear in storage";
16
17    function __get($name) {
18        $args = func_get_args();
19        echo "In " . __METHOD__ . "(" . implode(',', $args) . ")\n";
20    }
21    function __set($name, $value) {
22        $args = func_get_args();
23        echo "In " . __METHOD__ . "(" . implode(',', $args) . ")\n";
24    }
25    function __isset($name) {
26        $args = func_get_args();
27        echo "In " . __METHOD__ . "(" . implode(',', $args) . ")\n";
28    }
29    function __unset($name) {
30        $args = func_get_args();
31        echo "In " . __METHOD__ . "(" . implode(',', $args) . ")\n";
32    }
33
34}
35$obj = new C;
36$ao = new UsesMagic($obj);
37echo "\n--> Write existent, non-existent and dynamic:\n";
38$ao->a = 'changed';
39$ao->dynamic = 'new';
40$ao->dynamic = 'new.changed';
41echo "  Original wrapped object:\n";
42var_dump($obj);
43echo "  Wrapping ArrayObject:\n";
44var_dump($ao);
45
46echo "\n--> Read existent, non-existent and dynamic:\n";
47var_dump($ao->a);
48var_dump($ao->nonexistent);
49var_dump($ao->dynamic);
50echo "  Original wrapped object:\n";
51var_dump($obj);
52echo "  Wrapping ArrayObject:\n";
53var_dump($ao);
54
55echo "\n--> isset existent, non-existent and dynamic:\n";
56var_dump(isset($ao->a));
57var_dump(isset($ao->nonexistent));
58var_dump(isset($ao->dynamic));
59echo "  Original wrapped object:\n";
60var_dump($obj);
61echo "  Wrapping ArrayObject:\n";
62var_dump($ao);
63
64echo "\n--> Unset existent, non-existent and dynamic:\n";
65unset($ao->a);
66unset($ao->nonexistent);
67unset($ao->dynamic);
68echo "  Original wrapped object:\n";
69var_dump($obj);
70echo "  Wrapping ArrayObject:\n";
71var_dump($ao);
72?>
73--EXPECT--
74--> Write existent, non-existent and dynamic:
75In UsesMagic::__set(a,changed)
76In UsesMagic::__set(dynamic,new)
77In UsesMagic::__set(dynamic,new.changed)
78  Original wrapped object:
79object(C)#1 (4) {
80  ["a"]=>
81  int(1)
82  ["b"]=>
83  int(2)
84  ["c"]=>
85  int(3)
86  ["priv":"C":private]=>
87  string(6) "secret"
88}
89  Wrapping ArrayObject:
90object(UsesMagic)#2 (2) {
91  ["b"]=>
92  string(29) "This should appear in storage"
93  ["storage":"ArrayObject":private]=>
94  object(C)#1 (4) {
95    ["a"]=>
96    int(1)
97    ["b"]=>
98    int(2)
99    ["c"]=>
100    int(3)
101    ["priv":"C":private]=>
102    string(6) "secret"
103  }
104}
105
106--> Read existent, non-existent and dynamic:
107In UsesMagic::__get(a)
108NULL
109In UsesMagic::__get(nonexistent)
110NULL
111In UsesMagic::__get(dynamic)
112NULL
113  Original wrapped object:
114object(C)#1 (4) {
115  ["a"]=>
116  int(1)
117  ["b"]=>
118  int(2)
119  ["c"]=>
120  int(3)
121  ["priv":"C":private]=>
122  string(6) "secret"
123}
124  Wrapping ArrayObject:
125object(UsesMagic)#2 (2) {
126  ["b"]=>
127  string(29) "This should appear in storage"
128  ["storage":"ArrayObject":private]=>
129  object(C)#1 (4) {
130    ["a"]=>
131    int(1)
132    ["b"]=>
133    int(2)
134    ["c"]=>
135    int(3)
136    ["priv":"C":private]=>
137    string(6) "secret"
138  }
139}
140
141--> isset existent, non-existent and dynamic:
142In UsesMagic::__isset(a)
143bool(false)
144In UsesMagic::__isset(nonexistent)
145bool(false)
146In UsesMagic::__isset(dynamic)
147bool(false)
148  Original wrapped object:
149object(C)#1 (4) {
150  ["a"]=>
151  int(1)
152  ["b"]=>
153  int(2)
154  ["c"]=>
155  int(3)
156  ["priv":"C":private]=>
157  string(6) "secret"
158}
159  Wrapping ArrayObject:
160object(UsesMagic)#2 (2) {
161  ["b"]=>
162  string(29) "This should appear in storage"
163  ["storage":"ArrayObject":private]=>
164  object(C)#1 (4) {
165    ["a"]=>
166    int(1)
167    ["b"]=>
168    int(2)
169    ["c"]=>
170    int(3)
171    ["priv":"C":private]=>
172    string(6) "secret"
173  }
174}
175
176--> Unset existent, non-existent and dynamic:
177In UsesMagic::__unset(a)
178In UsesMagic::__unset(nonexistent)
179In UsesMagic::__unset(dynamic)
180  Original wrapped object:
181object(C)#1 (4) {
182  ["a"]=>
183  int(1)
184  ["b"]=>
185  int(2)
186  ["c"]=>
187  int(3)
188  ["priv":"C":private]=>
189  string(6) "secret"
190}
191  Wrapping ArrayObject:
192object(UsesMagic)#2 (2) {
193  ["b"]=>
194  string(29) "This should appear in storage"
195  ["storage":"ArrayObject":private]=>
196  object(C)#1 (4) {
197    ["a"]=>
198    int(1)
199    ["b"]=>
200    int(2)
201    ["c"]=>
202    int(3)
203    ["priv":"C":private]=>
204    string(6) "secret"
205  }
206}
207