PHP Serialization with private 属性 & getters & setters



我有一个基类,该基类使用php魔法方法__get和__set能够在扩展类中修改私有属性。然后,我为相关的私人属性构建了setter getter函数(类似于此处的内容http://www.beaconfire-red.com/epic-stuff/better-getter-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"(中获取公共属性,但它不会拾取私有属性(即" IE"(_地位"(这是序列化函数:

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

基础类中的上述方法是否可以识别子类中的所有getters,以便将它们包括在序列化中?换句话说,我希望序列化同时包括" ID"one_answers"状态"

我意识到我可以在课堂上获取所有方法,并使用某种命名约定来识别Getter/Setter,但我特别需要将Getter/Setter名称保持与属性名称相同,IE _STATUS必须具有Gettersetter称为状态((那么,还有其他方法可以识别这些特定功能吗?

也许有点不同的方法:

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

您也可以将其序列化。此方法使用儿童课上的公共Getter方法。

使用反射和反射property :: 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;
    }

这是为了回答明确的问题。但是我不确定您是否应该使用此设计来解决您的问题。

我正在采用不同的方法……我认为我更喜欢它而不是反射。但是很想听听别人是否同意。

我将根据访问何时在子类中注册每个getter/setter,即,我将将getter/setter名称存储在数组中。在序列化时,我不仅会在所有公共属性上交叉,而且还将在注册的getter/setter上交叉。

这是我在基类中注册(存储getter/setter名称(,将其存储在一个名为_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;
    }
}

现在,在我的序列化中,我还检索了任何注册的getters并将它们序列化。它运行良好!

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

这种方法有任何问题?

最新更新