Laravel 13中使用UUID作主键需三步:迁移中用$table->uuid('id')->primary();模型设$incrementing = false和$keyType = 'string';在creating事件中用Str::uuid()生成并强转字符串。

Laravel 13 中使用 UUID 作为模型主键,需同时完成数据库迁移配置、模型属性声明和主键自动生成逻辑三部分。缺一不可,否则会出现插入失败、查不到数据、路由 404 等问题。
迁移文件:定义 UUID 主键字段
在创建表的迁移中,明确使用 uuid() 并设为主键:
- 必须调用 ->primary(),否则不是主键,插入时会报错 “Field 'id' doesn't have a default value”
- 不要加 ->unique() —— 主键已隐含唯一性,多余写法可能引发警告或兼容问题
- Laravel 13+ 支持原生
$table->uuid('id')->primary(),无需额外扩展
示例:
php ```php Schema::create('users', function (Blueprint $table) { $table->uuid('id')->primary(); $table->string('name'); $table->timestamps(); }); ```模型类:声明主键类型与非自增行为
模型中必须显式设置两个关键属性,否则 Eloquent 仍按整型自增逻辑处理:
-
$incrementing = false:关闭自增假设,让
save()、create()尊重你赋的值 -
$keyType = 'string':确保
find('xxx-xxx')、路由绑定、关联查询全部走字符串比较,避免被转成 0 导致查不到 - 若主键字段名不是
id(如叫uuid),还需设置 $primaryKey = 'uuid'
示例:
php ```php class User extends Model { public $incrementing = false; protected $keyType = 'string'; // protected $primaryKey = 'uuid'; // 仅当字段名不是 id 时启用 } ```自动生成:在 creating 事件中填充 UUID
推荐在模型 boot() 中监听 creating 事件,在保存前生成并赋值。不建议用构造函数或访问器,它们不参与批量插入或工厂创建。
- 使用 Str::uuid()(Laravel 内置,基于 OpenSSL,足够安全)
- 务必强转为 (string),避免对象被序列化或比较出错
- 加
if (!$model->id)判断,允许手动指定 ID(如测试或迁移场景)
示例:
php ```php use Illuminate\Support\Str;protected static function boot() { parent::boot();
static::creating(function ($model) {
if (!$model->id) {
$model->id = (string) Str::uuid();
}
});}
<H3>可选增强:用 ramsey/uuid 提升标准性与性能</H3> <p>如需 RFC 4122 兼容、更高熵或 v7/v8 时间有序 UUID,可引入 <strong>ramsey/uuid</strong>:</p> <ul> <li>安装:<code>composer require ramsey/uuid</code></li> <li>替换生成逻辑:<code>$model->id = (string) \Ramsey\Uuid\Uuid::uuid4();</code></li> <li>生产环境推荐,尤其涉及多服务或审计要求高的系统</li> </ul>


















