Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP访问子对象';父对象中的私有属性_Php_Oop_Serialization_Protected - Fatal编程技术网

PHP访问子对象';父对象中的私有属性

PHP访问子对象';父对象中的私有属性,php,oop,serialization,protected,Php,Oop,Serialization,Protected,我有一个父对象,用于我的应用程序中的常规CRUD—它有基本的保存和检索方法,所以我不必在我的所有对象中重新包含它们。我的大多数子对象都扩展了此基础对象。这很好,但我发现检索序列化的子对象有问题。我在父对象中使用一个“retrieve”方法,该方法创建子对象的实例,然后从未序列化子对象的属性填充它自己——这意味着它可以“自未序列化”对象 唯一的问题是-如果子对象具有受保护的或私有的属性,则父对象无法读取它,因此在检索过程中不会拾取它 因此,我正在寻找一种更好的“自我取消序列化”方法,或者一种允许父

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

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

因此,我正在寻找一种更好的“自我取消序列化”方法,或者一种允许父对象“查看”受保护的属性的方法,但仅限于在检索过程中

代码示例:

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

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

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

似乎没有相同的类可见性策略应用于iherited/父类。php文档没有解决这个问题

我建议您将retrieve方法声明为static,并通过静态调用而不是当前的“self-unserialize”方法获取$cleanTester

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

[...]

$cleanTester = BaseObject::retrieve();
或者您可以使用
\u get()
方法访问不可访问的属性。。。我相信这可以添加到
BaseObject
类中,并从子类获取受保护的属性。由于相同的类可见性策略应该应用于
BaseObject
,因此可以定义
\u get()
方法private或protected

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

    return null;
  }
试着这样做:

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;
  }
}

解决这个问题的最好办法是使用反射

例如:


谢谢-这主意不错,但由于baseobject不知道孩子的属性,所以它不知道该问什么。静态方法似乎是可行的——但事实上,一些子对象需要重新设置,并且在它们计算出应该从中检索的文件名之前,需要进行一些处理。已经使用了_get,基本上就是为了这个目的——但是当我遍历对象的属性时,父对象同样不知道要请求什么属性。我想我需要看看迭代方法-谢谢指针。
$_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) "" }