在 PHP 中,JsonSerializable 接口是处理对象序列化为 JSON 的重要工具。它允许对象自定义 JSON 编码的行为,特别是在使用 json_encode() 时非常方便。在 Laravel 项目中,掌握如何正确实现 JsonSerializable::jsonSerialize 方法,不仅能提升数据传输的灵活性,还能使 API 返回结构更符合业务需求。
本文将带你深入理解 JsonSerializable,并通过一个 Laravel 实战案例,展示如何应用它来定制 JSON 输出。
JsonSerializable 是 PHP 5.4 版本引入的接口,声明了一个方法:
public function jsonSerialize();
该方法返回的数据会被 json_encode() 用作序列化内容。通过实现这个接口,类可以完全控制被转换成 JSON 的数据结构。
Laravel 本身使用 Eloquent ORM 处理模型数据,通常模型会自动转换成 JSON。但有些场景你可能想要:
自定义 JSON 返回字段和格式;
过滤敏感信息(如密码、令牌);
嵌套关联数据时更灵活地调整结构;
简化前端处理的复杂度。
这时,JsonSerializable 就非常合适。
假设我们有一个 User 模型,包含字段:
id
name
password
created_at
updated_at
我们希望:
输出时隐藏 password;
将 created_at 格式化为简洁时间字符串;
添加一个计算属性 profile_url。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use JsonSerializable;
class User extends Model implements JsonSerializable
{
// 允许批量赋值字段(根据需要)
protected $fillable = ['name', 'email', 'password'];
// 需要隐藏的字段
protected $hidden = ['password'];
public function jsonSerialize()
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at->format('Y-m-d H:i'),
'profile_url' => url('gitbox.net/profile/' . $this->id),
];
}
}
<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller
{
public function show($id)
{
$user = User::findOrFail($id);
// 直接返回对象,Laravel 会调用 jsonSerialize 自动序列化
return response()->json($user);
}
}
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
Route::get('user/{id}', [UserController::class, 'show']);
访问 http://gitbox.net/user/1 返回:
{
"id": 1,
"name": "张三",
"email": "[email protected]",
"created_at": "2025-05-25 10:30",
"profile_url": "http://gitbox.net/profile/1"
}
可以看到:
password 字段被隐藏了;
created_at 格式美化了;
新增了 profile_url 字段。
JsonSerializable 接口让你可以完全控制模型序列化为 JSON 的行为;
在 Laravel 中结合 Eloquent 使用非常方便,兼容性好;
适用于 API 输出定制、敏感数据保护、格式统一等场景;
配合 Laravel 的 response()->json() 方法,使用简洁、直观。
如果你需要对 JSON 数据结构有更细粒度的掌控,JsonSerializable::jsonSerialize 是不可或缺的利器。