它似乎不起作用:
$ref = new ReflectionObject($obj);
if($ref->hasProperty('privateProperty')){
print_r($ref->getProperty('privateProperty'));
}
它进入IF循环,然后抛出一个错误:
属性privateProperty不存在
:|
$ref = new ReflectionProperty($obj, 'privateProperty')
也不起作用。。。
文档页面列出了一些常量,包括IS_PRIVATE
。如果我不能访问私人财产,我怎么能使用它呢?哈哈?
class A
{
private $b = 'c';
}
$obj = new A();
$r = new ReflectionObject($obj);
$p = $r->getProperty('b');
$p->setAccessible(true); // <--- you set the property to public before you read the value
var_dump($p->getValue($obj));
更新:从PHP 8.1.0开始,调用ReflectionProperty::setAccessible方法无效;默认情况下,所有属性都可以访问。
请注意,如果您需要获得来自父类的私有属性的值,则接受的答案将不起作用。
为此,您可以依赖反射API的getParentClass方法。
此外,这个微库已经解决了这个问题。
更多详细信息,请参阅此博客文章。
getProperty
抛出异常,而不是错误。重要的是,你可以处理它,并为自己节省一个if
:
$ref = new ReflectionObject($obj);
$propName = "myProperty";
try {
$prop = $ref->getProperty($propName);
} catch (ReflectionException $ex) {
echo "property $propName does not exist";
//or echo the exception message: echo $ex->getMessage();
}
要获取所有私有属性,请使用$ref->getProperties(ReflectionProperty::IS_PRIVATE);
如果您需要而不需要反射:
public function propertyReader(): Closure
{
return function &($object, $property) {
$value = &Closure::bind(function &() use ($property) {
return $this->$property;
}, $object, $object)->__invoke();
return $value;
};
}
然后像这样使用它(在同一类中):
$object = new SomeObject();
$reader = $this->propertyReader();
$result = &$reader($object, 'some_property');
没有反射,也可以进行
class SomeHelperClass {
// Version 1
public static function getProperty1 (object $object, string $property) {
return Closure::bind(
function () use ($property) {
return $this->$property;
},
$object,
$object
)();
}
// Version 2
public static function getProperty2 (object $object, string $property) {
return (
function () use ($property) {
return $this->$property;
}
)->bindTo(
$object,
$object
)->__invoke();
}
}
然后像
SomeHelperClass::getProperty1($object, $propertyName)
SomeHelperClass::getProperty2($object, $propertyName)
应该起作用。
这是Nikola Stojiljković答案