Код, который я предоставляю ниже, бессмысленен, потому что я отредактировал таким образом, с помощью которого легко проводить тесты.
Кстати, в моем случае 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();
?>
Вывод скрипта — ничто.
Что мне не хватает?
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;};
}
}
Других решений пока нет …