如何在PHP中获取对象的受保护属性

2022-08-30 08:53:37

我有一个对象,其中包含一些我想要获取和设置的受保护属性。对象如下所示

Fields_Form_Element_Location Object
(
[helper] => formText
[_allowEmpty:protected] => 1
[_autoInsertNotEmptyValidator:protected] => 1
[_belongsTo:protected] => 


[_description:protected] => 
[_disableLoadDefaultDecorators:protected] => 
[_errorMessages:protected] => Array
    (
    )

[_errors:protected] => Array
    (
    )
[_isErrorForced:protected] => 
[_label:protected] => Current City


[_value:protected] => 93399
[class] => field_container field_19 option_1 parent_1
)

我想获取对象的属性。当我尝试或它产生错误。我搜索并找到了要使用的解决方案。它在我的本地工作,但在服务器上PHP版本是所以我不能在那里使用这个功能。那么任何解决方案如何获得这样的财产呢?value$obj->_value$obj->valuePHP Reflection Class5.2.17


答案 1

以下是如何使用的真正简单的示例(没有错误检查):ReflectionClass

function accessProtected($obj, $prop) {
  $reflection = new ReflectionClass($obj);
  $property = $reflection->getProperty($prop);
  $property->setAccessible(true);
  return $property->getValue($obj);
}

我知道你说你仅限于5.2,但那是2年前,5.5是最古老的支持版本,我希望能帮助人们使用现代版本。


答案 2

对象可以类型转换为(关联)数组,并且受保护成员的密钥以前缀(请参阅此处@fardelian的注释)。使用此未累积的功能,您可以编写“暴露器”:chr(0).'*'.chr(0)

function getProtectedValue($obj, $name) {
  $array = (array)$obj;
  $prefix = chr(0).'*'.chr(0);
  return $array[$prefix.$name];
}

或者,可以从序列化字符串中分析值,其中(似乎)受保护的成员具有相同的前缀。

这在 PHP 5.2 中有效,没有反射类的开销。但是,某些属性在客户端代码中受到保护和隐藏是有原因的。读取或写入可能会使数据不一致,或者作者提供了一些其他方法来公开它,以使接口尽可能精简。当有理由直接读取受保护的属性时,正确的方法是实现__get()魔术方法,因此请始终检查是否有任何方法,看看它的作用。这种反直觉的查找最终在 PHP 8.1 中通过只读属性得到了解决。

从 PHP 8.0 开始,反射类还可以访问属性元数据,请确保在执行尝试闯入受保护成员之前也检查它们。属性取代了“注释”1,因此也请检查它们。

1:注释对客户端编码人员来说是一个非常讨厌的惊喜:他们解析注释以添加疯狂的花哨黑盒无用的混乱功能,不应该再使用,但它们仍然存在


推荐