在我们构建Json API的时候, 我们常常会遇到需要将我们的模型或者关系转化为Json的或者数组情况,Eloquent模型中有简便的方法可以帮助我们做这些转换工作,也可以帮助我们控制那些属性可以在你的串行化内容中。
如果我们想将一个模型以及他加载的关系转换为一个数组, 我们通常使用toArray方法,这个方法是递归执行的,因此它可以将多层级的所有属性和关系都转换为数组。
$user = App\User::with('roles')->first();
return $user->toArray();
如果我们只是转化模型本身的属性为数组,我们可以使用attributesToArray
方法
$user = App\User::first();
return $user->attributesToArray();
当然我们也可以把整个模型转换为数组(这个是不包括加载的关系的)
$users = App\User::all();
return $users->toArray();
如果想要把一个模型转换为Json, 我们应该使用toJson
方法, 和toArray
方法一样, 这个方法也是递归的,因此所有的属性和关系都会被转化为Json, 我们甚至可以把PHP原生支持的json_encode拿到这里来用
$user = App\User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);
除此之外, 如果你把那个模型或者Collection当做字符串来处理的时候, 也会在模型上自动调用toJson
方法。
$user = App\User::find(1);
return (string) $user;
如果模型和Collection被声明为字符串, 我们甚至可以直接在路由或者模型中返回Eloquent对象
Route::get('users', function () {
return App\User::all();
});
当Eloquent模型转化为Json的时候,它所加载的关联关系也会自动包括在Json的属性当中,
== 注意: 模型自带的属性 将会使用驼峰命名法, 而所加载的关系将会使用蛇形命名法来表示。 ==
有的时候我们可能会希望隐藏一些包含在模型中的属性, 如password这样的,此时我们应当在模型中定义一个 $hidden属性,将需要隐藏的属性放在这里。
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
* @var array
*/
protected $hidden = ['password'];
}
== 注意 当需要隐藏关系的时候 我们应当使用关系的方法名称 ==
除此之外我们也可以使用,visiable 属性来定义白名单, 在转换为json或者数组的时候, 处理白名单中的内容 其他的都会被隐藏
如果你在定义了hidden属性的模型中, 想要hidden属性中的字段临时显现出来我们可以使用makeVisible
方法 , 相反如果你在定义了visiable属性的墨香中想要隐藏掉visiable中的一些属性 我们就可以使用 makehidden
方法
return $user->makeVisible('attribute')->toArray();
return $user->makeHidden('attribute')->toArray();
在某些情况下, 当我们把一个模型转为数组或者Json的时候我们需要将一个不是模型的属性添加到内容中, 这个时候 第一步我们要创建一个Accessor(Accessor是什么参见mutator章节)
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Get the administrator flag for the user.
* @return bool
*/
public function getIsAdminAttribute()
{
return $this->attributes['admin'] === 'yes';
}
}
创建了Accessor之后,我们需要添加对应的属性到模型的appends
中, == 注意 尽管在创建Accessor的时候用的是驼峰命名法, 但是在添加到appends中的时候我们应该使用蛇形命名法
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The accessors to append to the model's array form.
* @var array
*/
protected $appends = ['is_admin'];
}
属性一旦添加到append属性的时候, 在转换为json或者数组的时候就会包括这些属性,在使用的时候我们可以使用append
方法追加一个属性, 亦或者你也可以使用setAppends
方法来覆盖模型中的整个append属性
通过覆盖父类中的serializeDate
方法我们可以自定义默认的日期串行化方式,
/**
* Prepare a date for array / JSON serialization.
* @param \DateTimeInterface $date
* @return string
*/
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d');
}
通过在Eloquent模型中的$cast属性中添加属性类型声明, 同样可以实现上述串行方式修改, 不同的是它可以对每个属性做不同的串行话修改
protected $casts = [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];