PHP在父级中访问子级的私有属性

Posted

技术标签:

【中文标题】PHP在父级中访问子级的私有属性【英文标题】:PHP Accessing a child's private properties in parent 【发布时间】:2011-03-29 21:20:49 【问题描述】:

我有一个父对象,用于在我的应用程序中进行一般 CRUD - 它具有基本的保存和检索方法,因此我不必将它们重新包含在我的所有对象中。我的大多数子对象都扩展了这个基础对象。这工作正常,但我发现检索序列化子对象存在问题。我在创建子对象实例的父对象中使用“检索”方法,然后从未序列化子对象的属性中填充自身 - 这意味着可以“自我反序列化”对象。

唯一的问题是 - 如果子对象具有受保护或私有属性,则父对象无法读取它,因此在检索期间不会被拾取。

所以我正在寻找一种更好的“自我反序列化”方法,或者一种允许父对象“看到”受保护属性的方法 - 但仅限于检索过程中。

代码示例:

BaseObject 

 protected $someparentProperty;

 public function retrieve() 

  $serialized = file_get_contents(SOME_FILENAME);
  $temp = unserialize($serialized);
  foreach($temp as $propertyName => $propertyValue) 
    $this->$propertyName = $propertyValue;
       

 

 public function save() 

    file_put_contents(SOME_FILENAME, serialize($this));
 


class ChildObject extends BaseObject 

 private $unretrievableProperty;  

 public setProp($val) 
    $this->unretrivableProperty = $val;
 


$tester = new ChildObject();
$tester->setProp("test");
$tester->save();

$cleanTester = new ChildObject();
$cleanTester->retrieve();
// $cleanTester->unretrievableProperty will not be set

已编辑:应该说“私人”不受保护的子属性。

【问题讨论】:

【参考方案1】:

解决此问题的最佳方法是使用反射。 示例:

$_SESSION[''] = ''; // init

class Base 
    public function set_proxy()
        $reflectionClass = new ReflectionClass($this);
        $ar = $reflectionClass->getDefaultProperties();

        !isset($ar['host'])  or  $_SESSION['host'] = $ar['host'];
    


class Son1 extends Base 
    private $host = '2.2.2.2';


class Son2 extends Son1 




$son1 = new Son1();
$son1->set_proxy(); 
var_dump($_SESSION); // array(2)  [""]=> string(0) "" ["host"]=> string(7) "2.2.2.2" 

unset($_SESSION);
$_SESSION[''] = ''; // init

$son2 = new Son2();
$son2->set_proxy(); 
var_dump($_SESSION); //  array(1)  [""]=> string(0) "" 

【讨论】:

【参考方案2】:

试试这样:

abstract class ParentClass

  protected abstract function GetChildProperty();

  public function main()
  
    $value = $this->GetChildProperty();
  


class ChildClass extends ParentClass

  private $priv_prop = "somevalue";

  protected function GetChildProperty()
  
    return $this->priv_prop;
  

【讨论】:

【参考方案3】:

似乎同一类可见性策略不适用于继承/父类。 php 文档没有解决这个问题。

我建议您将检索方法声明为静态,并通过静态调用而不是您当前的“自我反序列化”方法获取 $cleanTester。

static function retrieve() 
  $serialized = file_get_contents(SOME_FILENAME);
  return unserialize($serialized);


[...]

$cleanTester = BaseObject::retrieve();

或者您可以利用__get() 方法访问不可访问的属性...我相信这可以添加到BaseObject 类并从子类中获取受保护的属性。由于相同的类可见性策略应适用于 BaseObject,因此您可以定义 __get() 方法 private 或 protected。

BaseObject 
  private function __get($propertyName) 
    if(property_exists($this,$propertyName))
      return $this->$propertyName;

    return null;
  

【讨论】:

谢谢。静态方法似乎是可行的——但事实上,一些子对象需要被实例化,并在它们可以计算出应该从中检索的文件名之前进行一些处理。 __get 已经被使用了,几乎就是为了这个目的——但是当我遍历对象的属性时,父级再次不知道要请求什么属性。我想我需要看看迭代方法 - 感谢指针。【参考方案4】:

子对象中的 getProperty() 函数如何返回 $this->unretrievableProperty

【讨论】:

谢谢 - 好主意,但由于 baseobject 不知道孩子的属性,它不知道要求什么

以上是关于PHP在父级中访问子级的私有属性的主要内容,如果未能解决你的问题,请参考以下文章

从父级中的子级访问元素标记名

父级中的Java方法占位符在子级中使用[重复]

css父级没包住子级是怎么回事,我用firebug查看,确实在父级的div中,但是就是没有包括子级的内容

Java - 为啥另一个包中的子级无法通过父级引用访问父级的受保护方法?

React,将在父级创建的引用传递给子级

如何有效地通过 React 中父级的引用访问子级?