Определите методы получения / установки с помощью eval и __call в переполнении стека

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

Кстати, в моем случае ParentClass является классом базы данных, а методы setter / getter используются для выбора и обновления полей таблицы.

<?php

abstract class ParentClass {

protected static
$properties = []
;

public function __construct() {
foreach (static::$properties as $property) {
$setterName = "Set".ucfirst($property);
$this->$setterName = eval('function($value){$this->'.$property.' = $value;};');
$getterName = "Get".ucfirst($property);
$this->$getterName = eval('function(){return $this->'.$property.';};');
}
}

public function __call($method, $args) {
if (isset($this->$method)) {
$func = $this->$method;
return call_user_func_array($func, $args);
}
}

}

class ChildClass extends ParentClass {

protected static
$properties = [
"property1"]
;

protected
$property1
;

}

$childClass = new ChildClass();
$childClass->SetProperty1("value");
echo $childClass->GetProperty1();

?>

Вывод скрипта — ничто.

Что мне не хватает?

1

Решение

eval возвращается NULL, если только return где-то в evalРед. код. В настоящее время, когда вы устанавливаете $this->$setterName, что твое eval на самом деле это создает закрытие, а затем выбрасывает его (потому что он не используется иным образом), возвращает NULLи ты заводишься с $this->SetProperty1 = NULL;,

Вместо этого вы должны использовать замыкания напрямую:

public function __construct() {
foreach (static::$properties as $property) {
$setterName = "Set".ucfirst($property);
$this->$setterName = function($value) use($property) {$this->$property = $value;};
$getterName = "Get".ucfirst($property);
$this->$getterName = function() use($property) {return $this->$property;};
}
}
2

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

Других решений пока нет …

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