在PHP中使用eval和__call定义getter / setter方法

时间:2016-02-03 21:26:11

标签: php eval setter getter

我提供的代码是没有意义的,因为我编辑的方式很容易进行测试。

在我的例子中,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 个答案:

答案 0 :(得分:2)

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