1--TEST--
2Reflection and property_exists()
3--FILE--
4<?php
5
6class A
7{
8    public    $a = 1;
9    protected $b = 2;
10    private   $c = 3;
11
12    public    $empty;
13    public    $init = 1;
14
15    function __toString()
16    {
17        return 'obj(' . get_class($this) . ')';
18    }
19
20    static function test($oc, $props)
21    {
22        echo '===' . __CLASS__ . "===\n";
23        foreach($props as $p2) {
24            echo $oc, '::$' , $p2, "\n";
25            var_dump(property_exists($oc, $p2));
26        }
27    }
28}
29
30class B extends A
31{
32    private   $c = 4;
33
34    static function test($oc, $props)
35    {
36        echo '===' . __CLASS__ . "===\n";
37        foreach($props as $p2) {
38            echo $oc, '::$' , $p2, "\n";
39            var_dump(property_exists($oc, $p2));
40        }
41    }
42}
43
44class C extends B
45{
46    private   $d = 5;
47
48    static function test($oc, $props)
49    {
50        echo '===' . __CLASS__ . "===\n";
51        foreach($props as $p2) {
52            echo $oc, '::$' , $p2, "\n";
53            var_dump(property_exists($oc, $p2));
54        }
55    }
56}
57
58$oA = new A;
59$oA->e = 6;
60
61$oC = new C;
62
63$pc = array($oA, 'A', 'B', 'C', $oC);
64$pr = array('a', 'b', 'c', 'd', 'e');
65
66foreach($pc as $p1) {
67    if (is_object($p1)) {
68        $p1->test($p1, $pr);
69    } else {
70        $r = new ReflectionMethod($p1, 'test');
71        $r->invoke(NULL, $p1, $pr);
72    }
73    echo "===GLOBAL===\n";
74    foreach($pr as $p2) {
75        echo $p1, '::$' , $p2, "\n";
76        var_dump(property_exists($p1, $p2));
77    }
78}
79
80echo "===PROBLEMS===\n";
81try {
82    var_dump(property_exists(NULL, 'empty'));
83} catch (\TypeError $e) {
84    echo $e->getMessage() . \PHP_EOL;
85}
86try {
87    var_dump(property_exists(25,'empty'));
88} catch (\TypeError $e) {
89    echo $e->getMessage() . \PHP_EOL;
90}
91var_dump(property_exists('',''));
92var_dump(property_exists('A',''));
93var_dump(property_exists('A','123'));
94var_dump(property_exists('A','init'));
95var_dump(property_exists('A','empty'));
96var_dump(property_exists(new A, ''));
97var_dump(property_exists(new A, '123'));
98var_dump(property_exists(new A, 'init'));
99var_dump(property_exists(new A, 'empty'));
100?>
101--EXPECT--
102===A===
103obj(A)::$a
104bool(true)
105obj(A)::$b
106bool(true)
107obj(A)::$c
108bool(true)
109obj(A)::$d
110bool(false)
111obj(A)::$e
112bool(true)
113===GLOBAL===
114obj(A)::$a
115bool(true)
116obj(A)::$b
117bool(true)
118obj(A)::$c
119bool(true)
120obj(A)::$d
121bool(false)
122obj(A)::$e
123bool(true)
124===A===
125A::$a
126bool(true)
127A::$b
128bool(true)
129A::$c
130bool(true)
131A::$d
132bool(false)
133A::$e
134bool(false)
135===GLOBAL===
136A::$a
137bool(true)
138A::$b
139bool(true)
140A::$c
141bool(true)
142A::$d
143bool(false)
144A::$e
145bool(false)
146===B===
147B::$a
148bool(true)
149B::$b
150bool(true)
151B::$c
152bool(true)
153B::$d
154bool(false)
155B::$e
156bool(false)
157===GLOBAL===
158B::$a
159bool(true)
160B::$b
161bool(true)
162B::$c
163bool(true)
164B::$d
165bool(false)
166B::$e
167bool(false)
168===C===
169C::$a
170bool(true)
171C::$b
172bool(true)
173C::$c
174bool(false)
175C::$d
176bool(true)
177C::$e
178bool(false)
179===GLOBAL===
180C::$a
181bool(true)
182C::$b
183bool(true)
184C::$c
185bool(false)
186C::$d
187bool(true)
188C::$e
189bool(false)
190===C===
191obj(C)::$a
192bool(true)
193obj(C)::$b
194bool(true)
195obj(C)::$c
196bool(false)
197obj(C)::$d
198bool(true)
199obj(C)::$e
200bool(false)
201===GLOBAL===
202obj(C)::$a
203bool(true)
204obj(C)::$b
205bool(true)
206obj(C)::$c
207bool(false)
208obj(C)::$d
209bool(true)
210obj(C)::$e
211bool(false)
212===PROBLEMS===
213property_exists(): Argument #1 ($object_or_class) must be of type object|string, null given
214property_exists(): Argument #1 ($object_or_class) must be of type object|string, int given
215bool(false)
216bool(false)
217bool(false)
218bool(true)
219bool(true)
220bool(false)
221bool(false)
222bool(true)
223bool(true)
224