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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20334355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:05:44  来源:igfitidea点击:

How to get protected property of object in PHP

phpobjectprotectedphp-5.2

提问by Awais Qarni

I have a object having some protected property that I want to get and set. The object looks like

我有一个对象具有一些我想要获取和设置的受保护属性。对象看起来像

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
)

I want to get valueproperty of the object. When I try $obj->_valueor $obj->valueit generates error. I searched and found the solution to use PHP Reflection Class. It worked on my local but on server PHP version is 5.2.17So I cannot use this function there. So any solution how to get such property?

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

采纳答案by álvaro González

That's what "protected" is meant for, as the Visibilitychapter explains:

这就是“受保护”的含义,正如可见性章节所解释的:

Members declared protected can be accessed only within the class itself and by inherited and parent classes.

声明为 protected 的成员只能在类本身内以及被继承类和父类访问。

If you need to access the property from outside, pick one:

如果您需要从外面进入该物业,请选择一个:

  • Don't declare it as protected, make it public instead
  • Write a couple of functions to get and set the value (getters and setters)
  • 不要将其声明为受保护的,而是将其公开
  • 编写几个函数来获取和设置值(getter 和 setter)

If you don't want to modify the original class (because it's a third-party library you don't want to mess) create a custom class that extends the original one:

如果您不想修改原始类(因为它是您不想弄乱的第三方库),请创建一个扩展原始类的自定义类:

class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}

... and add your getter/setter there.

...并在那里添加您的 getter/setter。

回答by drewish

Here's the really simple example (with no error checking) of how to use ReflectionClass:

这是如何使用的非常简单的示例(没有错误检查)ReflectionClass

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

I know you said you were limited to 5.2, but that was 2 years ago, 5.5 is the oldest supported versionand I'm hoping to help people with modern versions.

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

回答by Jan Turoň

Object can be typecasted into (associative) array and the protected members have keys prefixed with chr(0).'*'.chr(0)(see @fardelian's comment here). Using this undocummented feature you can write an "exposer":

对象可以被类型转换为(关联)数组,并且受保护的成员具有前缀为的键chr(0).'*'.chr(0)(请参阅此处的@fardelian 评论)。使用这个未记录的功能,您可以编写一个“exposer”:

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

Alternatively, you can parse the value from serializedstring, where (it seems) protected members have the same prefix (I hope php 5.2 didn't change it).

或者,您可以从序列化字符串中解析值,其中(似乎)受保护的成员具有相同的前缀(我希望 php 5.2 没有更改它)。

回答by user2782001

If you want to tinker with a class without adding getters and setters....

如果你想在不添加 getter 和 setter 的情况下修改一个类......

PHP 7 adds a call($obj) method (faster than old bindTo) on closures allowing you to call a function so the $thisvariable will act just as it would within a class -with full permissions.

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 

回答by Charlie

If you cannot modify the original class and extending it is not an option either, you can use the ReflectionProperty interface.

如果您不能修改原始类并且扩展它也不是一个选项,您可以使用 ReflectionProperty 接口。

The phptoolcase library has a handy method for this:

phptoolcase 库有一个方便的方法:

$value = PtcHandyMan::getProperty( $your_object , ‘propertyName');

Static property from a singleton class:

来自单例类的静态属性:

$value = PtcHandyMan::getProperty( ‘myCLassName' , ‘propertyName');

You can find the tool here: http://phptoolcase.com/guides/ptc-hm-guide.html

您可以在此处找到该工具:http: //phptoolcase.com/guides/ptc-hm-guide.html

回答by stephen

  $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']));