【问题标题】:(De)serialize field containing JSON automatically when model is created创建模型时自动(反)序列化包含 JSON 的字段
【发布时间】:2013-04-16 05:57:04
【问题描述】:

我该怎么做呢?当我从我的数据库中获取模型时,我想序列化和反序列化一个 JSON 字符串,这样我就可以直接访问 stdObject 而不必每次都自己反序列化它。

【问题讨论】:

    标签: json activerecord serialization yii


    【解决方案1】:

    我相信您可以将其添加到您的模型中,并更改爆炸/内爆以适应您的序列化/反序列化问题:

    内爆/爆炸:

    protected function afterFind() {
    
        parent::afterFind();
    
        if($this->hasAttribute('types'))
            $this->types = explode('|', $this->types);
    
        return $this;
    }
    
    protected function beforeSave() {
    
        parent::beforeSave();
    
        if($this->hasAttribute('types'))
            $this->types = implode('|', $this->types);
    
        return $this;
    }
    

    if 语句只是一个故障保险,以防数据库中缺少该字段(不太可能),或者如果您在基本模型中使用此代码(因为某些模型可能没有此字段)。在大多数情况下,排除此检查是安全的。

    JSON:

    protected function afterFind() {
    
        $this->types = json_decode($this->types);
        return parent::afterFind();
    }
    
    protected function beforeSave() {
    
        $this->types = json_encode($this->types);
        return parent::beforeSave();
    }
    

    【讨论】:

    • 我要的是 JSON,但这回答了我的问题。谢谢你。如果您可以为路人更新到 JSON,那就太好了。再次感谢。
    【解决方案2】:

    您也可以使用 getter/setter。假设我们的 DB 列名为 jsonData。然后你可以写

    public function getData()
    {
        return json_decode($this->jsonData);
    }
    
    public function setData($value)
    {
        $this->jsonData = json_encode($value);
    }
    

    data 然后可以像常规属性一样使用。

    【讨论】:

    • 使用 afterFind/beforeSave 的解决方案更加优雅。
    • 不同之处在于,您仍然可以访问 JSON 编码的数据。我不同意,其他解决方案更优雅。使用 getter 和 setter 是一种非常强大的技术,您应该习惯。
    • 自动转换属性总是一个坏主意。例如。在上述解决方案中,在save() 操作之后,您突然在types 中得到JSON(更糟糕的是,如果save() 操作失败,例如因为type 太长)。而在此解决方案中,您甚至可以独立验证这两个字段。现在这就是我所说的更优雅的方式。 :P
    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 2014-10-27
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多