I failed to get dynamic instance variables via PHP's reflection
Sample code:
<?php
class Foo
{
public function bar()
{
$reflect = new Reflect开发者_如何学JAVAionClass($this);
$props = $reflect->getProperties();
var_export($props);
die;
}
}
$foo = new Foo();
$foo->a = "a";
$foo->b = "b";
$foo->bar(); // Failed to print out variable a and b
Any idea?
ReflectionClass::getProperties()
gets only properties explicitly defined by a class. To reflect all properties you set on an object, use ReflectionObject
which inherits from ReflectionClass
and works on runtime instances:
$reflect = new ReflectionObject($this);
Or as Tim Cooper says, forget reflection and just use get_object_vars()
instead.
You cannot use ReflectionClass
in this situation. Replace your $props
variable with the following to make it work:
$props = get_object_vars($this);
If there is no other method you need to call from ReflectionObject
(see BoltClock's answer), then this is the simplest solution.
class Foo { }
$foo = new Foo();
$foo->a = "a";
$foo->b = "b";
echo Reflection::export(new ReflectionObject($foo));
// Object of class [ <user> class Foo ] {
// @@ /var/www/files/r.php 2-2
// - Constants [0] {
// }
// - Static properties [0] {
// }
// - Static methods [0] {
// }
// - Properties [0] {
// }
// - Dynamic properties [2] {
// Property [ <dynamic> public $a ]
// Property [ <dynamic> public $b ]
// }
// - Methods [0] {
// }
// }
A detailed explanation on both answeres above
Given the instance of an anonymous class
$object = new class()
{
private $fooPrivate = 'barPrivate';
public $fooPublic = 'barPublic';
public static $fooStaticPublic = 'barStaticPublic';
public function getProperties(): array
{
return get_object_vars( $this );
}
};
$object->fooDynamic = 'barDynamic';
Getting the properties by reflection
with ReflectionClass
/** lists: `fooPrivate`, `fooPublic`, `fooStaticPublic` */
var_export(
( new ReflectionClass( $object ) )
->getProperties()
);
/** lists: `fooPublic`, `fooStaticPublic` */
var_export(
( new ReflectionClass( $object ) )
->getProperties( ReflectionProperty::IS_PUBLIC )
);
with ReflectionObject
/** lists: `fooPrivate`, `fooPublic`, `fooStaticPublic`, `fooDynamic` */
var_export(
( new ReflectionObject( $object ) )
->getProperties()
);
/** lists: `fooPublic`, `fooStaticPublic`, `fooDynamic` */
var_export(
( new ReflectionObject( $object ) )
->getProperties( ReflectionProperty::IS_PUBLIC )
);
Getting the properties by get_object_vars()
/** lists: `fooPublic`, `fooDynamic` */
var_export(
get_object_vars( $object )
);
/** lists: `fooPrivate`, `fooPublic`, `fooDynamic` */
var_export(
$object->getProperties()
);
Summary
ReflectionClass::getProperties()
- cannot fetch dynamically assigned properties
ReflectionObject::getProperties()
- can fetch dynamically assigned properties
ReflectionClass::getProperties()
andReflectionObject::getProperties()
both- can fetch static properties
- can fetch properties no matter their defined access scope
- both can be called with a filter
get_object_vars()
- can fetch dynamically assigned properties
- cannot fetch static properties
- cannot fetch properties the calling scope does not have access to, which is absolutely correct in the way access modification is meant to work in OOP
精彩评论