PHP Доступ к закрытым свойствам ребенка в parent - PullRequest
3 голосов
/ 14 августа 2010

У меня есть родительский объект, который я использую для общего 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

РЕДАКТИРОВАНИЕ: Должен был сказать "Private" незащищенные дочерние свойства.

Ответы [ 4 ]

3 голосов
/ 19 января 2011

попробуйте так:

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;
  }
}
0 голосов
/ 10 мая 2015

Наилучший из возможных ответов - использовать отражения .

Пример:

$_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) "" }
0 голосов
/ 14 августа 2010

Не похоже, что та же политика видимости классов применяется к наследуемым / родительским классам.Документация php не решает эту проблему.

Я хотел бы предложить, чтобы вы объявили метод получения статическим и извлекли $ cleanTester с помощью статического вызова, а не используя свой текущий метод "самоуничтожения".

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

[...]

$cleanTester = BaseObject::retrieve();

Или вы можете использовать метод __get() для доступа к недоступным свойствам ... Я считаю, что это можно добавить к классу BaseObject и получить защищенные свойства из дочернего класса.Поскольку такая же политика видимости класса должна применяться к BaseObject, вы можете определить метод __get() как приватный или защищенный.

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

    return null;
  }
0 голосов
/ 14 августа 2010

как насчет функции getProperty () в дочернем объекте, которая возвращает $ this-> unretrievableProperty

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...