toJson() 默认调用 json_encode($this->toArray()),输出完全取决于 toArray() 结果,受 $hidden、$visible、$casts、$appends 及关联加载状态影响,日期默认转 ISO8601 格式。

toJson() 方法默认行为是什么
toJson() 不是 Laravel 模型的独立配置项,而是 Eloquent 模型继承自 JsonSerializable 接口后自动提供的方法。它本质是调用 json_encode($this->toArray()),所以输出结构完全取决于模型当前的 toArray() 结果。
常见错误现象:字段没出现、时间格式不对、关联数据丢失——这些问题不是 toJson() 本身的问题,而是 toArray() 阶段就已确定了内容。
- 模型未加载关联关系时,
toJson()不会自动包含它们(需显式调用load()或使用with()) - 受
$hidden、$visible、$casts、append属性影响 - 日期字段默认转为 ISO8601 字符串(如
"2024-05-20T14:30:00.000000Z"),由$dateFormat和序列化逻辑共同控制
怎么控制 toJson() 输出的字段和格式
核心在模型层干预 toArray() 的产出,而不是改 toJson() 本身。
- 用
$appends添加访问器字段(记得在访问器里加return $this->attribute;这类明确返回值) - 用
$casts控制字段类型转换(例如'is_active' => 'boolean'会让 JSON 中输出true/false而非"1") - 避免在
toArray()里手动拼数组——Laravel 7+ 已不推荐重写该方法;优先用makeHidden()/makeVisible()动态控制 - 若需彻底定制 JSON 结构,直接用
json_encode()+ 手动构造数组,绕过toJson()
示例:只暴露 id 和 name,且把 created_at 格式化为短日期
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
json
$user->makeVisible(['id', 'name'])
->makeHidden(['password', 'remember_token'])
->toArray();
// 再调用 toJson() 就只含指定字段
toJson() 的参数会影响什么
toJson() 支持传入 JSON_* 常量,但实际生效的非常有限:
-
$model->toJson(JSON_UNESCAPED_UNICODE):防止中文被转成\u4f60,常用 -
$model->toJson(JSON_PRETTY_PRINT):加缩进,仅调试用,API 返回别开 -
JSON_NUMERIC_CHECK等对模型 JSON 输出基本无效——因为 Eloquent 已经把数字转成字符串或整型,不再依赖 json_encode 的类型探测 - 不要传
JSON_THROW_ON_ERROR:Laravel 内部没做异常捕获,出错直接报错,不建议线上用
API 响应中直接 return $model 为什么比 toJson() 更好
Laravel 的响应自动调用模型的 toJson(),但更关键的是:它会走完整的响应生命周期,包括自动设置 Content-Type: application/json、支持中间件(如 CORS)、能被事件监听(ResponseSend)。
- 写
return $user;即可,框架自动处理序列化和头信息 - 写
return response()->json($user);是等价的,但多一层封装 - 写
return $user->toJson();是错的:返回的是字符串,Content-Type 变成text/html,前端解析失败 - 如果用了 API 资源(
Resource),必须用return new UserResource($user);,否则资源类的toArray()逻辑不会触发
容易被忽略的一点:模型里定义了 $dates 或用了 Carbon 实例的属性,若没在 $casts 里声明,toJson() 仍可能输出对象而非字符串——这不是 bug,是序列化时机早于 Carbon 的 toString 处理所致。

















