eloquent模型转数组/json必须用toarray()或tojson(),不可直接json_encode();前者递归处理关联、访问器、$casts及$hidden/$visible规则,后者仅是对前者的封装;关联需预加载,敏感字段用$hidden过滤,日期和json字段需正确配置。

直接用 toArray() 或 toJson() 就能完成模型到数组/JSON 的转换,但实际项目里字段丢失、关联为空、日期格式错乱、敏感数据泄露,往往不是方法没调对,而是没搞清控制权在哪儿——序列化行为由模型自身配置驱动,不是靠外部函数强行处理。
toArray() 和 toJson() 的本质区别
toJson() 本质就是先调 toArray(),再套一层 json_encode()。所以所有字段过滤、访问器触发、关联展开、$casts 转换,都发生在 toArray() 阶段。一旦你绕过它直接 json_encode($model),就会暴露私有属性、跳过 $hidden、忽略访问器、且可能因未加载关联引发递归崩溃。
-
toArray()返回纯 PHP 数组,可安全用于后续加工(如批量改日期格式、条件删键) -
toJson(JSON_PRETTY_PRINT)适合调试,但生产环境避免,增加传输体积 - 路由中直接
return User::all()是 OK 的,Laravel 内部会自动调toJson(),但前提是模型已预加载必要关联
关联不出现?90% 是没 load
Eloquent 从不“自动 eager load”。toArray() 只序列化当前内存中已存在的数据,不管逻辑上该不该有。比如 User::find(1)->posts 返回 null,toArray() 里 'posts' => [],不是 null,也不是报错——这容易被误判为“没数据”,实则是没加载。
用于端到端视频本地化流程的轻量编排器,路由至四个专注子技能——/wjs-transcribing-audio、/wjs-translating-subtitles...
- 必须显式调用
with('posts')或load('posts')才会在数组中生成'posts'键 -
belongsTo关系(如Post->user())默认只存user_id,toArray()不会反查,得加with('user') - 循环中逐个
load()是典型 N+1,统一用with()预加载 -
setRelation('foo', $model)手动绑定的关系会被toArray()序列化,但不走访问器逻辑
$hidden 对所有序列化路径都生效,且不可逆
$hidden = ['password', 'remember_token'] 会同时影响 toArray()、toJson()、API Resource 输出。它是一道硬隔离,不是开关——一旦声明,就无法在某个接口里“临时放开”。
- 动态权限场景(如管理员可见密码哈希),别依赖
$hidden,改用 API Resource 的when()或手动except(['password']) - 隐藏关联需填关联方法名,如
protected $hidden = ['roles'],不是'role'或'roles_id' -
$visible是白名单,未列出的字段全被过滤,比$hidden更激进,慎用 -
makeHidden(['xxx'])可临时移除字段,但仅对当前实例有效,不改变类定义
JSON 字段(如 meta)的 cast 必须匹配操作方式
数据库字段设为 $table->json('meta') 后,模型里 $casts = ['meta' => 'array'] 才算配对成功。否则,whereJsonContains() 会失效,$user->meta['theme'] 读出来可能是字符串而非数组。
-
'array':读取为关联数组,写入时自动json_encode();空数组存为"[]",不是NULL -
'object':读取为stdClass,写入接受对象;传关联数组进去仍会编码成[],不是{} - 混用风险:模型设
'array',代码又手动json_encode($arr)再赋值,结果存成"{\"name\":\"foo\"}"(双重 JSON 字符串) - 查询嵌套值优先用
whereJsonContains('meta->notifications', ['email' => true]),别依赖where('meta->notifications->email', true),后者仅 MySQL 5.7+ 原生 JSON 字段支持
最常被忽略的一点:序列化不是“把模型变成字符串”的终点,而是数据出口的起点。真正难的不是怎么转,而是转之前有没有把该加载的关联加载好、该过滤的字段过滤干净、该格式化的日期格式对、该校验的 JSON 字段内容合法。这些控制点分散在迁移、模型定义、查询构造、甚至数据库配置里,漏掉任意一环,前端拿到的 JSON 就可能出人意料。










