应重写模型的 toArray() 方法,遍历并 unset 值为 null 的字段,保留 0、false、空字符串等有效值,确保关联模型也做同样处理。

模型序列化时怎么跳过 null 字段
默认情况下,Laravel 的 Eloquent 模型转 JSON(比如用 toJson() 或 API 返回响应)会把值为 null 的字段也输出为 "field": null。这不是 bug,是设计行为——但很多前端或接口规范要求“没值就不出现”,得手动干预。
最直接的方式是在模型里重写 toArray(),再让 JSON 序列化基于它。不要动 jsonSerialize(),它底层仍调用 toArray(),改这里更统一。
- 在模型中添加
protected $casts = ['field' => 'string']不影响 null 输出,只管类型转换 - 别用
appends+ 访问器模拟“条件字段”,那只是加字段,不删字段 - 如果字段是数据库里允许为 NULL 的列,且你不想改 schema,那就必须在序列化层过滤
Laravel 9+ 推荐:用 hidden + makeHidden() 动态处理?不推荐
hidden 是静态白名单/黑名单,不能按值动态决定是否隐藏。比如你想“当 middle_name 为 null 时才不输出”,hidden 做不到——它只认字段名,不看值。
有人试过在 toArray() 里用 unset(),但要注意:Eloquent 的 toArray() 返回的是副本数组,直接 unset 安全;但如果用了 append() 或访问器,得先调用父方法拿到完整数组再过滤。
- 错误写法:
return $this->attributes;—— 这是原始属性,含未转换的日期、布尔等,JSON 会出错 - 正确起点:
$array = parent::toArray(); - 过滤示例:
array_filter($array, fn($v) => $v !== null);—— 注意这会删掉0、false、空字符串,太激进 - 稳妥写法:遍历 + 显式判断
=== null
安全过滤 null 的 toArray() 实现
在模型里覆盖 toArray(),只剔除明确为 null 的字段,保留 0、false、'' 等有效值:
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
public function toArray()
{
$array = parent::toArray();
foreach ($array as $key => $value) {
if ($value === null) {
unset($array[$key]);
}
}
return $array;
}
这个逻辑简单、可预测,且不影响关系数据(toArray() 已递归处理关联模型)。如果你有深层嵌套关系并也要过滤,就得在关联模型里同样覆盖 toArray()。
- 别在
toJson()里做过滤——它只是包装了json_encode($this->toArray()) - 如果用了
Resource类(如UserResource),优先在 Resource 的toArray()里过滤,比改模型更灵活 - 注意:修改
toArray()后,firstOrCreate()、update()等写操作不受影响,只影响读出的结构
API 响应层统一处理(适合多模型场景)
如果多个模型都要过滤 null,又不想每个都重写 toArray(),可以在响应构造时统一后处理。例如在控制器或 API 资源集合里:
return response()->json(array_filter(
$user->toArray(),
fn($v) => $v !== null
));
但注意:这只能处理顶层字段,不会递归进 relations 数组。如果返回的是 Collection,要先 map() 再 array_filter。
- 用
Collection::map()处理列表时,记得最后调用values()重置键,否则 JSON 会变成对象而非数组 - 这种写法绕过了模型控制,调试时容易漏掉某处没加过滤
- 性能上几乎无差异,PHP 数组遍历 null 过滤成本极低
真正容易被忽略的是关系字段里的 null:比如 user->profile 是 null,但默认序列化仍会输出 "profile": null。这时候光过滤模型自身字段没用,得确保关联模型也实现了同样的 toArray() 逻辑,或者用 with() 前确认关联存在。

















