在Laravel雄辩模型中创建动态命名的变异器
我有一个日期字段列表,所有这些字段在它们的赋值符中都有相同的逻辑。我想将此功能提取到特征中,这样将来我所需要的就是在模型中创建日期字段数组并使用特征。
类似以下内容:
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 ));
};
}
解决方案
在回答您的具体问题之前,让我们先来看看能言善辩的变种是如何工作的。
能言善辩的变种人如何工作
所有雄辩的Model
派生类都有它们的__set()
和offsetSet()
方法来调用setAttribute
方法,该方法负责设置属性值并在需要时更改属性值。
在设置值之前,它检查:
- 自定义赋值方法
- 日期字段
- JSON浇注料和场地
进入流程
通过理解这一点,我们可以简单地进入流程并用我们自己的定制逻辑重载它。以下是一个实现:<?php
namespace AppModelsConcerns;
use IlluminateDatabaseEloquentConcernsHasAttributes;
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是唯一需要";动态命名muters";的用例,则根本不需要。您可能已经noticed,eloquent的日期字段可以由Laravel本身重新格式化:
class Whatever extends Model
{
protected $dates = [
'date_field_1',
'date_field_2',
// ...
];
protected $dateFormat = 'Y-m-d';
}
此处列出的所有字段都将按照$dateFormat
进行格式化。那我们就不要重新发明轮子了。
相关文章