创建动态Laravel访问器

时间:2017-11-22 16:04:07

标签: php laravel laravel-5.5

我有Product模型和Attribute模型。 ProductAttribute之间的关系很多。在我的Product模型上,我正在尝试创建一个动态访问器。我熟悉Laravel的访问器和mutator功能,记录为here。我遇到的问题是每次创建产品属性时都不想创建访问器。

例如,产品可能具有颜色属性,可以这样设置:

/**
 * Get the product's color.
 *
 * @param  string  $value
 * @return string
 */
public function getColorAttribute($value)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === 'color') {
            return $attribute->pivot->value;
        }
    }

    return null;
}

然后可以像$product->color那样访问产品的颜色。 如果我在产品中添加size属性,我需要在Product模型上设置另一个访问者,以便我可以像$product->size那样访问它。

有没有办法设置一个“动态”访问器来处理作为属性访问时的所有属性?

我是否需要用自己的功能覆盖Laravel的访问者功能?

3 个答案:

答案 0 :(得分:4)

是的,您可以将自己的逻辑片段添加到Eloquent Model类的getAttribute()函数中(在模型中覆盖它),但在我看来,这不是一个好习惯。

也许你可以有一个功能:

public function getProductAttr($name)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === $name) {
            return $attribute->pivot->value;
        }
    }

    return null;
}

并称之为:

$model->getProductAttr('color');

答案 1 :(得分:2)

覆盖魔术方法 - __ get()方法。

试试这个。

public function __get($key)
{
    foreach ($this->productAttributes as $attribute) {
        if ($attribute->code === $key) {
            return $attribute->pivot->value;
        }
    }

    return parent::__get($key);
}

答案 2 :(得分:0)

我认为ОлегШовкун答案可能是正确答案,但如果您确实想使用模型属性表示法,则可以通过类变量将所需的参数输入到模型中。

class YourModel extends Model{

  public $code;

  public function getProductAttribute()
  {
    //a more eloquent way to get the required attribute
    if($attribute = $this->productAttributes->filter(function($attribute){
       return $attribute->code = $this->code;
    })->first()){
        return $attribute->pivot->value;
    }

    return null;
  }
}

然后做

$model->code = 'color';
echo $model->product;

但它有点长而毫无意义