PHP Доступ к частной собственности дочернего объекта в родительском

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

EDITED: Должен был сказать «Частные» незащищенные детские свойства.

Related of "PHP Доступ к частной собственности дочернего объекта в родительском"

Не похоже, что политика видимости одного класса применима к классам iherited / parent. В документации php это не рассматривается.

Я бы предположил, что вы объявили метод retrieve static, и вытащил $ cleanTester через статический вызов, а не ваш текущий «самонасериализирующийся» подход.

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

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

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

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

Самый лучший ответ, чтобы исправить это, – использовать отражения .

Пример:

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