ThinkPHP6.0中Db::insertAll()是批量插入核心方法,通过单条INSERT VALUES(),()高效执行;需传入字段匹配的二维数组,返回影响行数,支持strict(false)过滤非法字段、replace()处理重复、array_chunk分片及事务保障。

ThinkPHP6.0 中使用 Db 类原生实现批量添加数据,核心是调用 insertAll() 方法,它底层通过 PDO 批量绑定参数执行一条 INSERT INTO ... VALUES (),(),... 语句,效率远高于循环单条插入。
基础用法:传入二维数组直接批量写入
确保数据结构为「关联二维数组」,每项字段名需与数据表字段严格对应(否则默认报错):
$data = [['name' => '张三', 'email' => 'z3@example.com'], ['name' => '李四', 'email' => 'l4@example.com']];$affected = Db::name('user')->insertAll($data);- 成功时返回实际插入的行数(整型),如
2;失败则抛出异常
规避字段不匹配报错:启用 strict(false)
若数组中存在数据库表里没有的字段(比如临时加的 source 或 tmp_flag),默认会抛出 InvalidArgumentException。可关闭严格模式,自动丢弃非法字段:
Db::name('user')->strict(false)->insertAll($data);- 注意:
strict(false)仅影响字段过滤,不影响主键/唯一索引冲突处理
处理主键或唯一键重复:用 replace() 或原生 SQL
insertAll() 默认不跳过重复记录,遇到主键/唯一索引冲突会整个批次失败。如需「存在则忽略、不存在则插入」,有两类方案:
立即学习“PHP免费学习笔记(深入)”;
- 用
replace()(MySQL 专用):Db::name('user')->replace()->insertAll($data);—— 底层转为REPLACE INTO,先删后插,可能影响自增 ID 和外键约束 - 更安全方式:手动拼
INSERT IGNORE或ON DUPLICATE KEY UPDATE,配合Db::execute()执行原生 SQL
大批量数据分片插入:避免超限和超时
单次 insertAll 建议控制在 500 条以内。超大量数据(如 10 万+)应主动分片,防止 MySQL max_allowed_packet 限制或 PDO 绑定参数过多:
- 按每批 300 条切分数组:
array_chunk($data, 300) - 结合
limit()并非真正分片,只是限制单次插入上限(TP6 支持但不常用):Db::name('user')->limit(300)->insertAll($data) - 推荐显式分批 + 事务包裹,增强可控性与回滚能力
不复杂但容易忽略:insertAll 返回的是影响行数,不是布尔值;出错必须靠 try/catch 捕获,不能只判断返回值是否大于 0。



















