ThinkPHP新增数据有三种方式:模型单条(触发验证/事件,推荐业务场景)、模型批量saveAll(全成功或全失败)、Db直写(无逻辑,高性能)。需字段过滤、事务控制及主键冲突处理。

ThinkPHP模型新增数据主要有三种常用方式:实例化赋值后保存、传参构造后保存、静态方法批量插入。核心区别在于是否触发验证器、修改器、事件等业务逻辑,以及是否支持字段过滤和事务控制。
单条数据新增(推荐用于带业务逻辑的场景)
模型新增会自动运行验证、自动完成、时间戳、事件钩子等,适合用户注册、订单创建等需校验与扩展的业务。
- 实例化后逐个赋值再保存:$user = new User(); $user->name = '张三'; $user->email = 'zhangsan@example.com'; $user->save();
-
构造时传数组再保存:$user = new User(['name' => '李四', 'email' => 'lisi@example.com']); $user->save();
注意:此方式跳过修改器,但会走验证器(若开启) - 使用 data() 批量赋值再保存:$user = new User(); $user->data(['name' => '王五', 'email' => 'wangwu@example.com']); $user->save();
- 务必字段过滤:避免直接用 $_POST,应配合 allowField(['name', 'email']) 或 Request::only(['name', 'email'])
- 获取自增ID:$user->save(); echo $user->id;(主键非 id 时,改用对应属性名,如 $user->user_id)
批量新增多条数据
适用于导入、同步、初始化等场景,性能优于循环单条插入,但要注意事务与失败回滚。
-
模型方式 saveAll():$list = [['name'=>'A'], ['name'=>'B']]; $user = new User(); $result = $user->saveAll($list);
优点:触发验证、自动时间戳、事件;缺点:任意一条失败则全部失败,不支持原生分批 -
静态 insert() 方法(TP8+):User::insert([['name'=>'C'], ['name'=>'D']]);
注意:不触发验证器、事件、修改器,仅执行 SQL 插入 - 大数据量建议分片处理:手动切分成每 500 条一组,循环调用 saveAll() 或 insertAll(),避免超时或内存溢出
Db 类直写新增(轻量无逻辑场景)
绕过模型层,直接执行 SQL,适合日志记录、缓存写入、后台脚本等无需业务约束的操作。
- 单条插入:Db::name('user')->insert(['name' => '赵六', 'email' => 'zhaoliu@example.com']);
- 插入并返回 ID:$id = Db::name('user')->insertGetId($data);(最常用)
- 批量插入:Db::name('user')->insertAll($list); 返回插入条数
- 安全控制:默认严格模式(字段不存在报错),可设为非严格:Db::name('user')->strict(false)->insert($data)
- REPLACE 支持(MySQL):Db::name('user')->insert($data, true) 或 insertAll($list, true)
关键注意事项
新增看似简单,但几个细节常被忽略,直接影响安全性与稳定性:
- 永远不要裸传 $_POST:必须用 allowField() 或 Request::only() 显式声明允许字段
- 高并发写入慎用 saveAll():TP8 明确提示其默认无事务包裹,无法保证原子性;需手动加 Db::transaction()
- 主键冲突处理:需覆盖写入时,模型用 replace()->save(),Db 类用 insert(..., true)
- 类型与格式校验应在控制器或验证器中完成:模型 save() 不做类型强制转换,错误数据可能导致插入失败或截断
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











