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