saveAll()必须传入二维数组,因底层需通过外层数组识别多条记录、子数组表示单条记录且键名须与字段严格一致;一维数组、对象集合、嵌套过深或含空元素均会导致失败。

是的,saveAll() 必须传入二维数组,这是硬性要求,不是可选格式。
为什么必须是二维数组?
saveAll 是模型方法,底层会逐条遍历数据并走模型字段映射、类型转换、自动时间戳等流程。它依赖数组结构来识别“每一条记录”:
- 外层数组代表“多条记录”的集合
- 每个子数组(如
['name' => 'A', 'email' => 'a@b.com'])代表一条完整记录 - 子数组的键名需与数据库字段名严格一致(或通过
field参数映射),否则该字段会被静默丢弃
常见非数组传参的错误情况
以下写法都会导致 saveAll 失败或返回 false:
- 传一维数组:
['name' => 'A', 'email' => 'a@b.com']→ 被当作单条数据但缺少“多条”结构,直接报错或静默失败 - 传对象集合但未实现可遍历接口(如未继承
Collection)→ 模型无法解析 - 嵌套过深:
[['data' => ['name' => 'A']]]→ 实际只有一条记录且字段在data下,模型找不到name字段 - 含空元素:
[[], ['name' => 'B']]→ 空数组触发校验中断,整批返回 false
可以传其他类型吗?
官方不支持直接传 JSON 字符串、对象实例、CSV 行或 Iterator。如果数据源是这些形式,必须先转换为标准二维数组:
立即学习“PHP免费学习笔记(深入)”;
- JSON 字符串:用
json_decode($json, true)转成关联数组 - 对象列表:用
array_map(fn($obj) => $obj->toArray(), $objects)统一转出 - 数据库查询结果(如 Db::select):本身已是二维数组,可直传(但注意字段名是否匹配模型)
小提醒:别被“模型实例”误导
有人误以为 new User() 是“一条数据”,于是写成 $model->saveAll([new User(), new User()]) —— 这不行。saveAll 不接受对象数组,只认键值对二维数组。若要用对象,得先调用 toArray()。



















