现在我们可以用各种方法将资料读取出来,不过通常读取後还要将资料做一些转换才适用,举个例子像是 boolean 栏位在 SQL 资料库里存的是数字的 0 跟 1,直接读出来的话也会是 0/1 ,通常我们会想要将这种栏位转换成 false/true 显示。
对於这种情况 Eloquent 就可以在 Model 中指定栏位做资料转换,这样读取出来的资料就会全部自行转换成一样的格式。
反过来也可以定义当写入资料时事先对资料做转换再储存。
如果是简单的资料格式转换的话,可以在 Model 中用 $casts 定义。
这边用 Todo 简单做示范,用 $casts 定义将 use_id 的值转换为布林值。
@@ -10,10 +10,22 @@ use App\Models\Tag;
class Todo extends Model
{
use HasFactory;
+
+ protected $casts = [
+ 'use_id' => 'boolean',
+ ];
试着读出来看看
可以看到本来是数字的 user_id 都变成 true 了。
casting 只会影响读取的值,当写入资料时还是依资料表的栏位型别储存。
casting 中比较常用到的是日期的转换,把 UTC 格式转成比较好视读的样子
protected $casts = [
'created_at' => 'datetime:Y-m-d',
];
如果不想把日期栏位一个个加到 casting ,可以定义一个共用的 serializeDate 转换函式
@@ -6,14 +6,30 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;
use App\Models\Tag;
+use DateTimeInterface;
class Todo extends Model
{
use HasFactory;
protected $fillable = [
'name',
];
+
+ protected function serializeDate(DateTimeInterface $date)
+ {
+ return $date->format('Y-m-d');
+ }
如果要做比较复杂的转换,读取资料可以经由 Accessor 做资料变换,以 Todo 为例,可以看到目前的资料全都是小写。
这时候在 Todo Model 中加上 Accessor getNameAttribute
/app/Models/Todo.php
@@ -14,6 +14,11 @@ class Todo extends Model
protected $fillable = [
'name',
];
+
+ public function getNameAttribute($value)
+ {
+ return strtoupper($value);
+ }
然後重新整理资料
资料库中的资料完全没变,读出来後变成全大写了。
因为定义了 getNameAttribute ,当经由 Todo Model 读取资料时就会对每个 name 栏位的资料执行转换,像这边是用 strtoupper 将资料转为全大写。
要让 Accessor 对应到栏位是经由函式的命名来设定
get<栏位的驼峰型>Attribute
举例来说
name -> getNameAttribute
first_name -> getFirstNameAttribute
这种参照法还有个有趣的用途,就是创造原本不存在的栏位。
像是在 Model 建立 getUpperNameAttribute 函式
public function getUpperNameAttribute()
{
return strtoupper($this->name);
}
getUpperNameAttribute 会将目前 Model 中的 name 值转为全大写後回传。
这时候用
Todo::first()->upper_name
会发现竟然能读到值,明明 Todo 没有 upper_name 这个栏位。
不过只是这样定义的话,就只有动态读取的时候能够取得 upper_name 的值,并不会常驻在资料结构中,像是用 Todo::get() 的话会发现没有 upper_name 。
如果希望读取出来的每个 Todo 都带有 upper_name 资料的话,要给 Model 追加定义 $appends 变数。
@@ -14,6 +14,13 @@ class Todo extends Model
protected $fillable = [
'name',
];
+ protected $appends = ['upper_name'];
public function getUpperNameAttribute()
{
return strtoupper($this->name);
}
Model 会根据 $appends 中的值寻找对应的 Accessor 读取资料後,加入到现有的 Model 回传当中。
注意只要有定义 $appends 就要为每个 append 的值定义 Accessor,不然找不到的话会直接报错。
资料读出来会先经过 casts 做转换,才根据 appends 追加栏位,这造成两种状况
像这边先把 name 转换成布林值後 upper_name 也受影响了
上面讲的都是读取资料的转换,Model 也可以定义在写入资料时的转换
@@ -6,14 +6,30 @@ class Todo extends Model
protected $fillable = [
'name',
];
+
+ public function setNameAttribute($value)
+ {
+ $this->attributes['name'] = strtolower($value);
+ }
一样要注意函式的命名
set<栏位的驼峰型>Attribute
另外 Mutator 不像 Accessor 可以直接回传值,必须赋值给 Model 上对应的栏位。
ProxmoxVE PVE VM 安装 ChromeOS ChromeOS 版本 Download ...
09-05-2021 React Component 是基於元件化的思考模式 本章内容 Compon...
工程师太师了: 第9话 杂记: 最近在泡咖啡 被同事问说: 你一天都喝几杯咖啡阿? 我的回答:我大概...
今天要讲讲数字的其他语法,那今天要讲的是Math.round( ) 那这个是要干嘛的呢,他其实就是四...
鱼儿水中游 教学原文参考:鱼儿水中游 这篇文章会介绍,如何在 Scratch 3 里使用角色移动、重...