Сериализация PHP с закрытыми атрибутами & amp; геттеры и усилители сеттеры

У меня есть базовый класс, который использует магические методы php __get и __set, чтобы иметь возможность изменять частные атрибуты в расширенном классе. Затем я построил установочные функции для соответствующих приватных атрибутов.
(похоже на то, что найдено здесь
http://www.beaconfire-red.com/epic-stuff/better-getters-and-setters-php
)

Поэтому мой дочерний класс будет выглядеть следующим образом:

class User extends BaseObject {
public $id = -1;
private $_status = "";function __construct($members = array()) {
parent::__construct($members);

}

//Setter/Getter
public function status($value = null) {
if($value) {
$this->_status = $value;

} else {
return $this->_status;
}
}

Теперь, когда я сериализую этот объект, который является методом JsonSerialize в базовом классе, сериализация будет получать только открытые атрибуты из дочернего класса (т. Е. «Id»), но не будет принимать частные атрибуты (т. Е. «_Status»)
Это функция сериализации:

 public function jsonSerialize() {
$json = array();
foreach($this as $key => $value) {

$json[$key] = $value;

}
return $json;
}

Есть ли способ, как вышеуказанный метод в базовом классе может идентифицировать всех геттеров в дочернем классе, чтобы они могли быть включены в сериализацию?
Другими словами, я хочу, чтобы сериализация включала в себя «id» и «status»

Я понимаю, что могу получить все методы в классе и использовать какое-то соглашение об именах для идентификации получателя / установщика, но мне нужно, чтобы имя получателя / установщика было таким же, как и имя атрибута, т.е. _status ДОЛЖЕН иметь установщик получателя с именем status ()
так есть ли другой способ идентифицировать эти конкретные функции?

1

Решение

использование отражение а также ReflectionProperty :: setAccessible:

    public function jsonSerialize()
{
$json = array();
$class = new ReflectionClass($this);
foreach ($class->getProperties() as $key => $value) {
$value->setAccessible(true);
$json[$value->getName()] = $value->getValue($this);

}
return $json;
}

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

0

Другие решения

Я иду с другим подходом … Я думаю, что я предпочитаю это вместо размышлений.
Но мне интересно узнать, согласны ли другие.

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

Вот когда я регистрируюсь (сохраняю имя получателя / установщика) в моем базовом классе, сохраняя его в массиве _getters.

function __set($name,$value){
if(method_exists($this, $name)){
$this->$name($value);
//save in getters list for serialization
if(!in_array($name,$this->_getters))
array_push($this->_getters,$name);
}
else{
// Getter/Setter not defined so set as property of object
$this->$name = $value;
}
}

И теперь в моей сериализации я также извлекаю любые зарегистрированные геттеры и сериализую их.
это работает хорошо!

    public function jsonSerialize() {
$json = array();
//do public properties

foreach($this as $key => $value) {
$json[$key] = $value;

}

//do any getter setters
foreach($this->_getters as $key => $getter) {
$value = $this->$getter;
$json[$getter] = $value;

}
return $json;
}

Есть проблемы с этим подходом?

0

Может быть, немного другой подход:

 public function toArray()
{
$descriptor = new \ReflectionClass(get_class($this));
/** @var \ReflectionMethod[] $methods */
$methods = $descriptor->getMethods(\ReflectionMethod::IS_PUBLIC);
$array   = [];
foreach ($methods as $method) {
if (substr_compare('get', $method->getName(), 0, 3) === 0) {
$property         = lcfirst(substr($method->getName(), 3));
$value            = $method->invoke($this);
$array[$property] = $value;
}
}

return $array;
}

Вместо того, чтобы возвращать массив, вы также можете его сериализовать. Этот подход использует общедоступные методы получения на дочерних классах.

0
По вопросам рекламы [email protected]