Laravel:创建一个动态属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25125724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:54:30  来源:igfitidea点击:

Laravel: create a dynamic property

phpmysqllaraveleloquent

提问by ewok

I have a decent-size codebase built at this point. I have a couple of tables with matching Eloquent models that are storing addresses in the form ### Street, City, ST, xzipx. These are represented in the database by a single varchar field called address.

我在这一点上构建了一个体面的代码库。我有几个带有匹配 Eloquent 模型的表,它们以### Street, City, ST, xzipx. 这些在数据库中由一个名为 的单个 varchar 字段表示address

Now here's my issue. I want to add a new feature that allows items to be compared by whether they are in the same city, state, etc. The way to do this as my database is currently configured is to tokenize the address string. This is fine, but a little annoying to have to do it every time.

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

The ideal solution would be to restructure the database, and associated models, to split the addressfield into street, city, state, and zip. The only problem there, would be that everywhere else, where I'm currently accessing the address using $model->address, I would have to construct it from the pieces. This happens a lot throughout the code, so even creating a helper function as below:

理想的解决方案将是重组的数据库和相关模型,对分裂address场分为streetcitystate,和zip。唯一的问题是,在其他任何地方,我当前正在使用 访问地址的地方$model->address,我必须从各个部分构建它。这在整个代码中经常发生,所以即使创建一个辅助函数如下:

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

would mandate replacing all instances of $model->addresswith $model->address(), which would still be cumbersome. The ideal solution would be to create a dynamic property, like how Laravel creates them using for relationships. Is this possible?

将强制替换$model->addresswith 的所有实例$model->address(),这仍然很麻烦。理想的解决方案是创建一个动态属性,就像 Laravel 如何使用关系创建它们。这可能吗?

Or is there a better solution?

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

回答by derekaug

You could define an accessor for the addressproperty:

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

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

Then, $object->addressshould return what you need. If you want it to be included on the model's array and JSON forms, you'll need to add it to the $appendsproperty of the model.

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

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

EDIT: for setting, you would have to set up a mutator, like so:

编辑:对于设置,您必须设置一个 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'];        
}