基于cast实现了类型的自动转换。
需求分析
我们需要开发活动管理,活动有开始时间和结束时间,数据库对时间统一使用int时间戳进行处理。
但是管理后台需要展示给管理员“年月日-时分秒”这类数据。
考虑到后续模块还会有这种需求,为了提高程序复用性,我不打算每个模块都CV代码,调研如何进行封装抽取,来实现类型的自动转化。
cast就是比较好的选择
下面开始上代码
代码实现
自定义基类model:
我定义了CustomModel
作为我的基类model,各模块的model层都会继承CustomModel
定义castAttribute
方法,所有需要类型转换的方法都会执行到这里
自定义属性custom_date
,返回return date('Y-m-d', intval($value));
当我需要返回指定格式的日期时,我就在对应的model,设置属性为custom_date
就可以了。
<?php namespace App\Model; use App\Library\Utility; use Illuminate\Database\Eloquent\Model; class CustomModel extends Model { . . . protected function castAttribute($key, $value) { switch ($this->getCastType($key)) { case 'int': case 'integer': return (int)$value; case 'real': case 'float': case 'double': return $this->fromFloat($value); case 'decimal': return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]); case 'string': return (string)$value; case 'bool': case 'boolean': return (bool)$value; case 'object': return $this->fromJson($value, true); case 'array': case 'json': return $this->fromJson($value); case 'collection': return new BaseCollection($this->fromJson($value)); case 'date': return $this->asDate($value); case 'datetime': case 'custom_datetime': return $this->asDateTime($value); case 'timestamp': return $this->asTimestamp($value); case 'geom': return Utility::decodePoint($value); case 'carray': return empty($value) ? [] : $this->fromJson($value); case 'not_empty': return empty($value) ? '[为空]' : $value; //定义自己的date格式 case 'custom_date': return date('Y-m-d', intval($value)); default: return $value; } } }
我们接着往下看
模块model层
需要使用时间戳转日期的model 设置$casts
注意:只有在model中设置了$casts
,才会执行上面CustomModel
中定义的类型转化函数castAttribute
。
特殊说明
下面的setStartTimeAttribute
和int时间戳自动转成日期进行展示没有关系。
setStartTimeAttribute
的作用是:保存时输入的日期字符串自动转成时间戳。
这样我们就智能的实现了时间戳和日期字符转的自动转换。
<?php namespace App\Model\House; class HouseGroupInfo extends CustomModel { protected $table = 'xxxx'; protected $primaryKey = 'id'; protected $connection = 'xxxx'; protected $keyType = 'int'; public $incrementing = true; protected $casts = [ 'endTime' => 'custom_date', 'startTime' => 'custom_date' ]; //设置setXXXAttribute方法,查看源码得知的,作用是:保存时输入的日期字符串转时间戳。 public function setStartTimeAttribute($value) { $this->attributes['startTime'] = strtotime($value); } public function setEndTimeAttribute($value) { $this->attributes['endTime'] = strtotime($value); } }
Controller层
<?php namespace App\Admin\Controllers; . . . class HouseGroupController extends AdminController { /** * Title for current resource. * * @var string */ protected $title = 'myTitle'; /** * Make a grid builder. * * @return Grid */ protected function grid() { $grid = new Grid(new HouseGroupInfo()); $grid->model()->orderBy('id', 'desc'); . . . $grid->column('startTime', '开始日期'); $grid->column('endTime', '结束日期'); $grid->column('createtime', '创建时间')->formatTimestamp(); $grid->actions(function ($actions) { // 去掉删除 $actions->disableDelete(); }); return $grid; } /** * Make a show builder. * * @param mixed $id * @return Show */ protected function detail($id) { $show = new Show(HouseGroupInfo::findOrFail($id)); return $show; } /** * Make a form builder. * * @return Form */ protected function form() { $form = new Form(new HouseGroupInfo()); $form->date('startTime', '活动开始日期')->format('YYYY-MM-DD')->width(200); $form->date('endTime', '活动结束日期')->format('YYYY-MM-DD')->width(200); $form->text('code', '邀请码')->rules("required|max:50"); $form->saving(function (Form $form) { //保存前的操作 钩子函数 if ($form->code) { } }); //保存后的操作:钩子函数 $form->saved(function (Form $form) { }); return $form; } }
小坑分享
注意:下面截图的set方式是设置值,xxx = yyy;
而不是return出去值,只有get方法才是return。
总结
这样我们就实现了基于Laravel的cast特性,实现了时间戳和自定义日期的自动转换。