首页 > php框架 > Laravel > 正文

在 Laravel 7 中优雅使用 UUID 教程

Guanhui
发布: 2020-05-25 11:29:13
转载
4121 人浏览过

在 Laravel 7 中优雅使用 UUID 教程

最近我不得不在 Laravel 7 实现 通用唯一识别码 ( UUIDs ),并遇到一些问题。我希望这帖子可为其他正在做相同事情的人解惑。

使用 UUIDs 的高级理由

A) 它们从你的 统一资源定位符 移除编号的 身份识别号 ,故用户不能看到你的应用已创建多少确定的对象。例如:

https://myapp.com/api/users/5
登录后复制

对比:

https://myapp.com/api/users/0892b118-856e-4a15-af0c-66a3a4a28eed
登录后复制

B) 它们让 身份识别号 远难于猜测。这有益于安全性,但我们可能应当实现其他技术以防范之。

作为主键实现 UUIDs

如何改变数据库迁移

首先,在数据库迁移中,你要将当前自动递增的 ID 字段替换为 UUIDs 。你还可以遵循以下方法:保留自动递增 ID 并将 UUID 作为表中的附加字段,在用户展示 URL 时使用 (在这种情况下,你将 ID 隐藏到模型中),但这不是我们能在这里做的。 让我们看看假设的 employees 表是什么样子的。

public function up()
    {
        Schema::create('employees', function (Blueprint $table) {
            $table->uuid('id')->primary;
            $table->string('name');
            $table->string('email')->unique();
            $table->string('work_location')->nullable();
            $table->timestamps();
        });
    }
登录后复制

在这里,注意我们用 uuid() 替换了 normal id() ;并使其成为主键。

让我们把它变成一种特质

接下来,我们可以实现 Laravel 生命周期挂钩,以确保在创建此模型的新实例时分配了 UUID。我们可以直接在模型中编写代码,但是如果你要在多个模型中使用 UUID,我建议用 Trait (我在这篇开发文章中学到了这一点,非常感谢 Dev)。trait 基本上允许你创建功能,并通过 use 关键字调用它在多个模型中使用。

要创建新的 Trait,请创建一个 \App\Http\Traits\文件夹 (这仅仅是我的爱好,你也可以将其放到其他位置),并为 Trait 创建一个新文件。我们将调用文件 UsesUuid.php。

这是 trait 的具体代码:

<?php
namespace App\Http\Traits;
use Illuminate\Support\Str;
trait UsesUuid
{
  protected static function bootUsesUuid() {
    static::creating(function ($model) {
      if (! $model->getKey()) {
        $model->{$model->getKeyName()} = (string) Str::uuid();
      }
    });
  }
  public function getIncrementing()
  {
      return false;
  }
  public function getKeyType()
  {
      return &#39;string&#39;;
  }
}
登录后复制

使用 \Illuminate\Support\Str 轻松生成 UUID.。getIncrementing () 方法告诉 Laravel 该模型的主键不会自增 (因为我们设置的是 false), 而 getKeyType () 方法告诉 Laravel 该模型的主键是字符串类型。bootUsesUuid () 方法允许我们使用 Laravel 强大的生命周期钩子。你可以 在这来哦藕节更多详细信息。基本上我们的代码已经可以告诉 Laravel,当创建该模型的新实例时,为其设置 UUID 主键!

现在,我们可以使用 use 关键字在模型上轻松实现此特征。

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
...
class Employee extends Model
{
    ...
    use \App\Http\Traits\UsesUuid;
    ...
}
登录后复制

将 UUID 引用为外键

要将表上的 UUID 引用为外键,只需更改表上外键字段的类型。如下...

 Schema::create(&#39;another_table&#39;, function(Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger(&#39;employee_id&#39;);
        $table->string(&#39;some_field&#39;);
        $table->foreign(&#39;employee_id&#39;)
            ->references(&#39;id&#39;)
            ->on(&#39;shifts&#39;)
            ->onDelete(&#39;cascade&#39;);
    });
登录后复制

... 我们在引用 employee_id 外键时创建了一个无符号大整型的数据类型,对此进行如下修改:

 Schema::create(&#39;another_table&#39;, function(Blueprint $table) {
        $table->id();
        $table->uuid(&#39;employee_id&#39;);
        $table->string(&#39;some_field&#39;);
        $table->foreign(&#39;employee_id&#39;)
            ->references(&#39;id&#39;)
            ->on(&#39;shifts&#39;)
            ->onDelete(&#39;cascade&#39;);
    });
登录后复制

那样简单!还有一件事...

UUID 和多态关系

您可能会发现自己通过自己的操作或要引入的包以多态关系引用了该模型。在迁移中,该表可能看起来像这样:

    public function up()
    {
        Schema::create(&#39;some_package_table&#39;, function (Blueprint $table) 
        {
            $table->bigIncrements(&#39;id&#39;);
            $table->morphs(&#39;model&#39;);
            ...
        }
    }
登录后复制

在这里,morphs () 方法将在数据库中创建两个字段,即无符号大整型类型的 model_id 和字符串类型的 model_type。问题在于我们的模型现在使用的是 UUID 而不是递增的整数 ID,因此这会给您带来错误,并显示类似以下内容::

Data truncated for column &#39;model_id&#39; at row 1
登录后复制

我们现在需要 model_id 字段来支持我们的新 UUID,它的类型是 CHAR (36)。别担心!Laravel 让这件事变得超级简单,你不需要手动做这件事。只需将迁移更改为:

    public function up()
    {
        Schema::create(&#39;some_package_table&#39;, function (Blueprint $table) 
        {
            $table->bigIncrements(&#39;id&#39;);
            $table->uuidMorphs(&#39;model&#39;);
            ...
        }
    }
登录后复制

爱 Laravel 的另一个原因!编码愉快!

推荐教程:《Laravel教程

以上是在 Laravel 7 中优雅使用 UUID 教程的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
php
来源:learnku.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板