create() 返回带ID的模型实例,save() 返回布尔值且ID需从模型属性读取,insertGetId() 直接返回ID但依赖自增主键;三者适用场景与行为差异明确。

在 Laravel 中,save() 或 create() 后拿不到 ID,通常不是“没返回”,而是你没正确使用返回值或忽略了 Eloquent 的行为差异。
create() 直接返回带 ID 的模型实例
create() 是最常用也最直接的方式:它会插入数据,并返回一个已加载 ID 的完整模型对象。前提是模型开启了 $fillable(或关闭了 $guarded),且数据库自增主键字段名为 id。
常见错误现象:var_dump($user->id) 为 null —— 很可能你调用了 new User([...])->save() 却误以为它像 create() 一样返回模型。
-
create()内部调用save()并返回$this,所以 ID 已存在 - 如果表主键不是
id(比如user_id),需在模型中设置protected $primaryKey = 'user_id'; - 若使用 UUID 或其他非自增主键,
create()仍返回模型,但 ID 是生成后赋值的,不依赖数据库返回
$user = User::create(['name' => 'Alice', 'email' => 'a@example.com']); echo $user->id; // ✅ 正常输出自增 ID
save() 后必须重新访问模型属性,不能依赖返回值
save() 方法本身返回的是布尔值(true / false),**不返回模型**。ID 是在保存成功后写入当前模型实例的属性中,不是函数返回值。
使用场景:需要在保存前做额外逻辑(如手动设置时间戳、关联 ID 等),或复用已有模型实例。
- 调用
$model->save()后,立刻读$model->id才是正确的 ID - 若模型未启用自动时间戳(
$timestamps = false),且你没手动设created_at,保存仍成功,但 ID 可用 - 注意:如果模型刚 new 出来但未填充任何属性,
save()可能因验证或数据库 NOT NULL 约束失败,此时$model->id仍是null
$user = new User(); $user->name = 'Bob'; $user->email = 'b@example.com'; $user->save(); // 返回 true,但不能写 $id = $user->save(); echo $user->id; // ✅ 正确获取 ID
insert() 和 insertGetId():绕过 Eloquent 模型,直操作查询构造器
当你只需要插入并立刻拿到 ID,且不关心模型事件、访问器、强制类型转换等 Eloquent 特性时,用查询构造器更轻量。
关键区别:insert() 不返回 ID(返回布尔值),insertGetId() 才返回新记录的主键值。
-
insertGetId()要求表必须有自增主键(默认id),否则抛出异常 - 传入数组必须是纯字段/值对,不走模型的
$fillable检查,也不触发creating等事件 - 性能略高,但丢失 Eloquent 层的安全与扩展能力,适合批量插入后的单条 ID 获取
$id = DB::table('users')->insertGetId([
'name' => 'Charlie',
'email' => 'c@example.com',
'created_at' => now()
]);
// $id 是整数,不是模型
事务中 ID 获取失败?检查是否用了 insert() 而非 insertGetId()
在事务里用 DB::table(...)->insert(...) 后试图读 $model->id,必然为空 —— 因为 insert() 没创建模型,也没给任何对象赋 ID。
容易踩的坑:
- 混合使用 Eloquent 和 Query Builder:一边用
User::create(),另一边又用DB::table('users')->insert(...),却期望后者也更新某个模型实例 - MySQL 8.0+ 在严格模式下,若插入时没提供非空字段值,
insertGetId()会报错,ID 拿不到 - PostgreSQL 需显式指定返回字段,
insertGetId()默认用RETURNING id,若主键名不是id会失败
复杂点在于:ID 的可用性取决于你走的是哪一层(Query Builder 还是 Eloquent)、主键定义是否匹配、以及数据库驱动的行为差异。别假设“插完就有 ID”,先确认你调用的是哪个方法、返回值是什么类型、有没有被事务或异常中断。


















