thinkphp批量添加数据应使用db::insertall()方法,传入二维关联数组生成单条多值insert语句,返回影响行数;需注意字段严格匹配、分片控制(如array_chunk)、事务包裹及replace()或原生sql处理重复。

用 Db::insertAll() 一次性插入多条
这是最常用也最高效的方式,底层生成一条 INSERT INTO table (a,b) VALUES (1,2),(3,4) 语句,只发一次 SQL:
- 数据必须是二维关联数组,每项键名严格对应数据库字段名(如
['name' => '张三', 'email' => 'z3@ex.com']
- 不能混入表中不存在的字段,否则 TP6 默认报错;可加
strict(false) 自动过滤:<code>Db::name('user')->strict(false)->insertAll($data) - 返回值是整数(影响行数),成功插 3 条就返回
3;失败会抛异常,不是 false 或 null,不能靠if ($res)判断
大批量数据必须主动分片
单次传入 5000 条?MySQL 很可能因 max_allowed_packet 拒绝,或 PHP 内存爆掉。正确做法是切块再循环:
- 用
array_chunk($data, 400)拆成每批 400 条的子数组 - 每批单独调用
Db::name('user')->insertAll($chunk) - 别在循环里反复写
Db::name('user'),复用一个实例更省资源
需要事务保障时,必须用 Db::transaction()
想保证“全成功或全失败”,不能手动 startTrans(),要用函数式事务入口:
Db::transaction(function () use ($chunks) { foreach ($chunks as $chunk) { Db::name('user')->insertAll($chunk); } });- 闭包内一旦抛出未捕获异常,事务自动回滚
- 闭包末尾记得
return true或其他值,否则 TP 可能不提交 - 事务内禁止混用
saveAll()(模型层)和insertAll()(Db 层),连接可能不一致,事务失效
想跳过重复记录?别依赖应用层判断
主键或唯一索引冲突时,insertAll() 默认整批失败。安全做法是:
- MySQL 环境可用
replace():Db::name('user')->replace()->insertAll($data)(先删后插,慎用,影响自增 ID) - 更推荐手写原生 SQL 配合
INSERT IGNORE或ON DUPLICATE KEY UPDATE,用Db::execute()执行 - 不要自己遍历查一遍再插——并发下仍有脏数据风险
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











