如何在PHP中获取对象的受保护属性
我有一个具有一些要获取和设置的受保护属性的对象。 该对象看起来像
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
)
我想获取对象的value属性。 当我尝试$obj->_value或$obj->value时,它会生成错误。 我搜索并找到了使用PHP Reflection Class的解决方案。它在我的本地环境中有效,但在服务器上的PHP版本是5.2.17,因此我无法在此处使用此功能。 那么任何解决方案如何获得这种财产?
6个解决方案
90 votes
这是如何使用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是受支持的最早版本,我希望可以帮助人们使用现代版本。
drewish answered 2020-01-22T19:08:15Z
45 votes
可以将对象类型转换为(关联)数组,并且受保护的成员具有以chr(0).'*'.chr(0)为前缀的键(请参阅此处的@fardelian的注释)。 使用此取消固定的功能,您可以编写一个“暴露者”:
function getProtectedValue($obj,$name) {
$array = (array)$obj;
$prefix = chr(0).'*'.chr(0);
return $array[$prefix.$name];
}
另外,您可以从序列化字符串中解析值,(似乎)受保护的成员具有相同的前缀(我希望php 5.2不会更改它)。
Jan Turoň answered 2020-01-22T19:08:40Z
22 votes
这就是“受保护”的含义,如“可见性”一章所解释:
声明为protected的成员只能在该类内部以及继承的和父类访问。
如果需要从外部访问该属性,请选择以下一项:
不要将其声明为受保护的,而是将其公开
编写几个函数来获取和设置值(getter和setter)
如果您不想修改原始类(因为它是一个第三方库,您不想弄乱),请创建一个扩展原始类的自定义类:
class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}
...然后在其中添加您的吸气剂/设置剂。
Álvaro González answered 2020-01-22T19:07:50Z
10 votes
如果您想在不添加getter和setter的情况下修改课程...。
PHP 7在闭包上添加了一个call($ obj)方法(比旧的bindTo更快),使您可以调用函数,因此$this变量将像在类中一样具有完全的权限。
//test class with restricted properties
class test{
protected $bar="protected bar";
private $foo="private foo";
public function printProperties(){
echo $this->bar."::".$this->foo;
}
}
$testInstance=new test();
//we can change or read the restricted properties by doing this...
$change=function(){
$this->bar="I changed bar";
$this->foo="I changed foo";
};
$change->call($testInstance);
$testInstance->printProperties();
//outputs I changed bar::I changed foo in php 7.0
user2782001 answered 2020-01-22T19:09:04Z
3 votes
如果您不能修改原始类,并且也不能扩展它,则可以使用ReflectionProperty接口。
phptoolcase库为此提供了一个方便的方法:
$value = PtcHandyMan::getProperty( $your_object , ‘propertyName’);
单例类的静态属性:
$value = PtcHandyMan::getProperty( ‘myCLassName’ , ‘propertyName’);
您可以在此处找到该工具:[http://phptoolcase.com/guides/ptc-hm-guide.html]
Charlie answered 2020-01-22T19:09:38Z
-1 votes
$propGetter = Closure::bind( function($prop){return $this->$prop;}, $element['field_text']['#object'], $element['field_text']['#object'] );
drupal_set_message('count='.count($propGetter('hostEntity')->field_captioned_carousel['und']));
stephen answered 2020-01-22T19:09:53Z