У меня есть родительский объект, который я использую для общего 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: Должен был сказать «Частные» незащищенные детские свойства.
Не похоже, что политика видимости одного класса применима к классам 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) "" }