`
[!注意]
关于如何更健壮地处理 Eloquent 模型和集合的 JSON 序列化,请查阅 Eloquent API 资源 的文档。
将模型及其已加载的 关联关系 转换为数组,你应该使用 toArray 方法。该方法是递归的,因此所有属性和所有关联关系(包括关联关系的关联关系)都将被转换为数组:
use App\Models\User;
$user = User::with('roles')->first();
return $user->toArray();该 attributesToArray 方法可用于将模型的属性转换为数组 但不包括其关联关系:
$user = User::first();
return $user->attributesToArray();你也可以将整个模型 集合 转换为数组,方法是调用集合实例上的 toArray 方法:
$users = User::all();
return $users->toArray();将模型转换为 JSON 时,您应该使用 toJson 方法。与 toArray 类似,toJson 方法是递归的,因此所有属性和关系都将转换为 JSON。您还可以指定 PHP 支持的 任何 JSON 编码选项:
use App\Models\User;
$user = User::find(1);
return $user->toJson();
return $user->toJson(JSON_PRETTY_PRINT);或者,您可以将模型或集合强制转换为字符串,这将自动调用模型或集合上的 toJson 方法:
return (string) User::find(1);因为模型和集合在转换为字符串时会被转换为 JSON,所以你可以直接从应用程序的路由或控制器返回 Eloquent 对象。当 Eloquent 模型和集合从路由或控制器返回时,Laravel 会自动将它们序列化为 JSON:
Route::get('/users', function () {
return User::all();
});当一个 Eloquent 模型转换为 JSON 时,其已加载的关系将自动作为 JSON 对象上的属性包含在内。此外,尽管 Eloquent 关系方法使用“驼峰式”命名法定义,但一个关系的 JSON 属性将是“蛇形命名法”。
有时您可能希望限制包含在模型数组或 JSON 表示中的属性,例如密码。
为此,请向您的模型添加一个 $hidden 属性。
列在 $hidden 属性数组中的属性将不会包含在模型的序列化表示中:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be hidden for serialization.
*
* @var array<string>
*/
protected $hidden = ['password'];
}[!NOTE]
为了隐藏关系,请将关系的方法名添加到你的 Eloquent 模型的$hidden属性中.
或者,您可以使用 visible 属性来定义一个属性的“允许列表”,这些属性应包含在模型的数组和 JSON 表示中。所有不在 $visible 数组中的属性,在模型转换为数组或 JSON 时都将被隐藏:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* The attributes that should be visible in arrays.
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}如果您想在给定的模型实例上显示一些通常隐藏的属性,可以使用 makeVisible 或 mergeVisible 方法。makeVisible 方法会返回模型实例:
return $user->makeVisible('attribute')->toArray();
return $user->mergeVisible(['name', 'email'])->toArray();同样地,如果您想隐藏一些通常可见的属性,您可以使用 makeHidden 或 mergeHidden 方法:
return $user->makeHidden('attribute')->toArray();
return $user->mergeHidden(['name', 'email'])->toArray();如果您希望临时覆盖所有可见或隐藏属性,您可以使用 setVisible 和 setHidden 方法,分别如下:
return $user->setVisible(['id', 'name'])->toArray();
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();偶尔,当您将模型转换为数组或 JSON 时,您可能希望添加一些在数据库中没有对应列的属性。为此,首先为该值定义一个访问器:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
/**
* Determine if the user is an administrator.
*/
protected function isAdmin(): Attribute
{
return new Attribute(
get: fn () => 'yes',
);
}
}如果你希望访问器始终附加到模型的数组和 JSON 表示中,你可以将属性名添加到模型的 appends 属性中。请注意,属性名通常使用它们的“蛇形命名法”序列化表示来引用,尽管访问器的 PHP 方法是使用“驼峰命名法”定义的:
<?php
namespace App\Models;
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'];
}一旦该属性被添加到 appends 列表中,它将同时包含在模型的数组和 JSON 表示中。在 appends 数组中的属性也将遵守模型上配置的 visible 和 hidden 设置。
在运行时,您可以指示模型实例使用 append 或 mergeAppends 方法附加额外的属性。或者,您可以使用 setAppends 方法覆盖给定模型实例的整个附加属性数组:
return $user->append('is_admin')->toArray();
return $user->mergeAppends(['is_admin', 'status'])->toArray();
return $user->setAppends(['is_admin'])->toArray();您可以自定义默认序列化格式,方法是覆盖 serializeDate 方法。此方法不影响日期在数据库中存储的格式:
/**
* Prepare a date for array / JSON serialization.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}您可以自定义单个 Eloquent 日期属性的序列化格式,方法是在模型的 类型转换声明 中指定日期格式:
protected function casts(): array
{
return [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];
}