【问题标题】:Creating dynamically named mutators in Laravel Eloquent models在 Laravel Eloquent 模型中创建动态命名的修改器
【发布时间】:2017-05-03 14:25:38
【问题描述】:

我有一个日期字段列表,所有这些字段在它们的 mutators 中都有相同的逻辑。我想将此功能提取到一个特征中,以便将来我需要在模型中创建一个日期字段数组并使用该特征。

类似这样的:

foreach( $dates as $date ) {
    $dateCamelCase = $this->dashesToUpperCase($date);
    $setDateFunctionName ='set'.$dateCamelCase.'Attribute';
    $this->{$setDateFunctionName} = function()  use($date) {
        $this->attributes[$date] = date( 'Y-m-d', strtotime( $date ));
    };
}

【问题讨论】:

  • 显示一些代码,以及你当前的尝试
  • 添加了我尝试的方式
  • @shaswa 你解决了吗?我有类似的情况并尝试相同。如果你能解决,请告诉我。
  • @Donkarnash:我做不到。由于时间紧迫,不得不为模型中的每个字段定义一个修改器。

标签: php laravel laravel-5 traits mutators


【解决方案1】:

在回答您的具体问题之前,让我们先看看 Eloquent mutators 是如何工作的。

雄辩的变异器如何工作

所有 Eloquent 的 Model 派生类都有其 __set()offsetSet() 方法来调用 setAttribute 方法,该方法负责设置属性值并在需要时对其进行变异。

在设置值之前,它会检查:

  • 自定义修改器方法
  • 日期字段
  • JSON castables 和字段

进入流程

通过了解这一点,我们可以简单地利用流程并使用我们自己的自定义逻辑对其进行重载。这是一个实现:

<?php

namespace App\Models\Concerns;

use Illuminate\Database\Eloquent\Concerns\HasAttributes;

trait MutatesDatesOrWhatever
{
    public function setAttribute($key, $value)
    {
        // Custom mutation logic goes here before falling back to framework's 
        // implementation. 
        //
        // In your case, you need to check for date fields and mutate them 
        // as you wish. I assume you have put your date field names in the 
        // `$dates` model property and so we can utilize Laravel's own 
        // `isDateAttribute()` method here.
        //
        if ($value && $this->isDateAttribute($key)) {
            $value = date('Y-m-d', strtotime($value));
        }

        // Handover the rest to Laravel's own setAttribute(), so that other
        // mutators will remain intact...
        return parent::setAttribute($key, $value);
    }
}

不用说,您的模型需要使用此特征来启用该功能。

你不需要它

如果mutating dates 是您需要“动态命名的修改器” 的唯一用例,则根本不需要这样做。正如你可能已经noticed,Laravel 本身可以重新格式化 Eloquent 的日期字段:

class Whatever extends Model 
{
    protected $dates = [
        'date_field_1', 
        'date_field_2', 
        // ...
    ];

    protected $dateFormat = 'Y-m-d';
}

那里列出的所有字段都将按照$dateFormat 格式化。那我们就不要重新发明轮子了。

【讨论】:

  • 如果需要重用访问器/修改器,您可能对 Eloquent Mutators 感兴趣 github.com/topclaudy/eloquent-mutators
  • 你也可以在你的模型中定义强制转换,简洁而优雅:protected $casts = [ 'your_field' => 'datetime:d/m/Y H:i:s', ];
  • 创建多个动态 mutator Traits 会多次调用模型 parent::setAttribute?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多