php - Laravel 模型动态属性

标签 php laravel dynamic attributes field

我想问如何在模型类上创建动态属性。假设我有一个如下代码所示的表结构。

Schema::create('materials', function (Blueprint $table) {
    $table->increments('id');
    $table->string('sp_number');
    $table->string('factory');
    $table->text('dynamic_fields')->comment('All description of the material will saved as json');
    $table->timestamps();
});

我的表结构中有一个名为“dynamic_fields”的列,它将保存字段的 JSON 字符串。下面是 JSON 结构的示例。

[  
   {  
      "name":"COLOR WAY",
      "value":"ASDFF12"
   },
   {  
      "name":"DESCRIPTION",
      "value":"agg2sd12"
   },
   {  
      "name":"REF NUM",
      "value":"121312"
   }
]

我想从动态字段访问字段,例如“COLOR WAY”。

在我的模型中,我想像这样访问动态字段上的“COLOR WAY”字段

$material->color_way;

有人可以告诉我该怎么做吗?

最佳答案

如果您提前知道只会有某些动态字段,您可以选择为它们创建访问器方法。例如,您可以将其添加到您的模型中:

// Dynamic fields must be cast as an array to iterate through them as shown below
protected $casts = [
    'dynamic_fields' => 'array'
];

// ...

public function getColorWayAttribute()
{
    foreach ($this->dynamic_fields as $field) {
        if ($field['name'] === 'COLOR WAY') {
            return $field['value'];
        }
    }

    return null;
}

这将允许您执行以下操作:

$colorWay = $material->color_way;

或者,如果您的 dynamic_fields 组合不受限制,可能有大量组合,或者您希望有更大的灵 active 以便能够添加更多组合并使其可访问,您可以重写 Laravel 模型类的 getAttribute 方法。

// Dynamic fields must be cast as an array to iterate through them as shown below
protected $casts = [
    'dynamic_fields' => 'array'
];

// ...

public function getAttribute($key)
{
    $attribute = parent::getAttribute($key);

    if ($attribute === null && array_key_exists('dynamic_fields', $this->attributes)) {
        foreach ($this->dynamic_fields as $dynamicField) {
            $name = $dynamicField['name'];
            if (str_replace(' ', '_', mb_strtolower($name)) === $key) {
                return $dynamicField['value'];
            }
        }
    }

    return $attribute;
}

这种方法调用 Laravel 的 getAttribute 实现,它首先检查您是否定义了实际的属性,或者是否为该属性定义了访问器(就像我的第一个建议中那样),然后检查是否有方法在基本模型类上以该名称存在,然后最终尝试加载关系(如果已定义)。

当每种方法都失败时(返回 null),我们会检查模型中是否存在 dynamic_fields 属性。如果有,我们循环遍历每个动态字段(假设您的 dynamic_fields 被转换为 array),然后将定义的动态字段的名称转换为小写并用下划线替换空格。然后,我们最后检查刚刚派生的名称是否与提供的键匹配,如果匹配,我们返回该值。如果不存在,则返回原始的 $attribute,即 null

这将允许您获取任何动态字段,就像它们被定义为类中的属性一样。

$colorWay = $material->color_way;
$description = $material->description;
$refNum = $material->ref_num;

请注意:我尚未测试此代码,很可能存在一两个问题。尝试一下,看看它是否适合您。另请注意,这仅适用于获取动态字段,设置它们将需要重写另一个方法。

关于php - Laravel 模型动态属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52551341/

相关文章:

MySQL 使用另一个表中的列名

php - 使用 PHP 创建动态表

javascript - 我如何 <input type ="text"onchange sql 查询?

javascript - 无法使用 Froala 编辑器将图像上传到本地服务器

php - 为我的属性表创建照片模型

mysql - Laravel 中如何通过数据透视表获取相关模型?

php - Laravel 自定义模型方法

android - 如何将自定义参数传递给 onClick 监听器

php - htaccess : Rewrite URL issue for query string in parameter

php - 如何计算动态创建的数组的长度?