ThinkPHP3.2 的 addAll() 成功时默认返回第一条记录主键 ID(整型),而非全部主键数组,因其底层使用批量 INSERT 语句,仅能通过 LAST_INSERT_ID() 获取首个自增 ID;可靠获取全部 ID 的方式包括手动递增计算、循环调用 add() 或原生 SQL 配合 ROW_COUNT()。

ThinkPHP3.2 的 addAll() 方法在成功执行后,**默认返回的是插入记录的第一条数据的主键 ID(整型)**,而不是所有新增记录的主键数组。这是它和单条 add() 的关键区别——add() 返回新记录 ID,addAll() 只返回起始 ID。
为什么 addAll() 不直接返回全部主键?
因为 TP3.2 的 addAll() 底层使用的是 INSERT INTO ... VALUES (...),(...),(...) 这类批量语句,MySQL 在执行时仅能通过 LAST_INSERT_ID() 获取**第一个生成的自增 ID**。框架未自动推算后续 ID(尤其当存在并发插入、触发器或非连续自增等情况时不可靠),所以不提供完整主键列表。
想拿到全部主键,有这几种可靠方式
-
手动计算(仅限纯自增、无并发、无触发器场景):若表主键为 INT 自增、每次插入 N 条、且期间无其他写入干扰,可基于返回值递增获取:
$firstId = $Model->addAll($dataList);<br>$allIds = range($firstId, $firstId + count($dataList) - 1);
-
分条插入 + 收集 ID(最稳妥):用循环调用
add(),逐条获取并存入数组:$allIds = [];<br>foreach ($dataList as $data) {<br> $id = $Model->add($data);<br> if ($id !== false) $allIds[] = $id;<br>} -
改用原生 SQL + LAST_INSERT_ID() 配合 ROW_COUNT():执行批量插入后,立即查:
SELECT LAST_INSERT_ID() AS first_id, ROW_COUNT() AS affected;
再在 PHP 中生成range($first_id, $first_id + $affected - 1)—— 前提仍是自增 ID 连续且安全。
注意事项
addAll() 对数组键名敏感:必须确保每条数据子数组的键名完全一致(如都含 'name'、'email'),否则字段错位。建议插入前统一用 ksort() 排序键名。
仅 MySQL 原生支持:TP3.2.3 以下版本的 addAll() 不兼容其他数据库(如 PostgreSQL、SQL Server)。



















