代码之家  ›  专栏  ›  技术社区  ›  Hippyjim

php访问父级中子级的私有属性

  •  3
  • Hippyjim  · 技术社区  · 16 年前

    我有一个在应用程序中用于常规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
    

    编辑:应该说“私人”不受保护的儿童财产。

    4 回复  |  直到 11 年前
        1
  •  0
  •   Ivar Bonsaksen    16 年前

    似乎同一个类可见性策略不适用于已筛选/父类。PHP文档没有解决这个问题。

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

    static function retrieve() {
      $serialized = file_get_contents(SOME_FILENAME);
      return unserialize($serialized);
    }
    
    [...]
    
    $cleanTester = BaseObject::retrieve();
    

    或者你可以利用 __get() 访问不可访问属性的方法…我相信这可以添加到 BaseObject 类并从子类获取受保护的属性。因为相同的类可见性策略应该应用于 基本对象 你可以定义 γ-() 方法私有或受保护。

    BaseObject {
      private function __get($propertyName) {
        if(property_exists($this,$propertyName))
          return $this->{$propertyName};
    
        return null;
      }
    
        2
  •  3
  •   Sim    15 年前

    尝试如下:

    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
  •  0
  •   CrayonViolent    16 年前

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

        4
  •  0
  •   shaun Steven X    11 年前

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

    例子:

    $_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) "" }