Laravel:创建一个动态属性

时间:2014-08-04 19:03:25

标签: php mysql laravel eloquent

此时我已经构建了一个体面的代码库。我有几个表与匹配的Eloquent模型,以### Street, City, ST, xzipx的形式存储地址。它们由一个名为address的varchar字段在数据库中表示。

现在这是我的问题。我想添加一个新功能,允许通过它们是否在同一个城市,州等进行比较。在我的数据库当前配置时,这样做的方法是对地址字符串进行标记。这很好,但每次都要这样做有点烦人。

理想的解决方案是重组数据库和相关模型,将address字段拆分为streetcitystate和{{1} }。那里唯一的问题是,在其他任何地方,我正在使用zip访问地址,我将不得不从这些部分构建它。这在整个代码中都会发生很多,所以即使创建一个辅助函数,如下所示:

$model->address

会强制将public function address(){ return $this->street.", ".$this->city.", ".$this->state." ".$this->zip; } 的所有实例替换为$model->address,这仍然很麻烦。理想的解决方案是创建动态属性,就像Laravel如何使用关系创建它们一样。这可能吗?

或者有更好的解决方案吗?

1 个答案:

答案 0 :(得分:13)

您可以为address属性定义一个访问者:

class YourClass {
    public function getAddressAttribute()
    {
        return $this->street.", ".$this->city.", ".$this->state." ".$this->zip;
    }
}

然后,$object->address应该返回您需要的内容。如果您希望它包含在模型的数组和JSON表单中,您需要将其添加到模型的$appends属性中。

class YourClass {
    protected $appends = array('address');
    public function getAddressAttribute()
    {
        return $this->street.', '.$this->city.', '.$this->state.' '.$this->zip;
    }
}

编辑:对于设置,你必须设置一个mutator,如下所示:

public function setAddressAttribute($value)
{
    // assume $this->handlesParsingAddress parses and returns an assoc array
    $parsed = $this->handlesParsingAddress($value);
    $this->street = $parsed['street'];
    $this->city = $parsed['city'];
    $this->state = $parsed['state'];
    $this->zip = $parsed['zip'];        
}