最近我不得不在 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 'string';
}
}
使用 \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('another_table', function(Blueprint $table) {
$table->id();
$table->unsignedBigInteger('employee_id');
$table->string('some_field');
$table->foreign('employee_id')
->references('id')
->on('shifts')
->onDelete('cascade');
});
... 我們在參考 employee_id 外鍵時創建了一個無符號大整型的資料型別,對此進行如下修改:
Schema::create('another_table', function(Blueprint $table) {
$table->id();
$table->uuid('employee_id');
$table->string('some_field');
$table->foreign('employee_id')
->references('id')
->on('shifts')
->onDelete('cascade');
});
那樣簡單!還有一件事...
UUID 和多型關系
您可能會發現自己通過自己的操作或要引入的包以多型關系參考了該模型,在遷移中,該表可能看起來像這樣:
public function up()
{
Schema::create('some_package_table', function (Blueprint $table)
{
$table->bigIncrements('id');
$table->morphs('model');
...
}
}
在這里,morphs () 方法將在資料庫中創建兩個欄位,即無符號大整型型別的 model_id 和字串型別的 model_type,問題在于我們的模型現在使用的是 UUID 而不是遞增的整數 ID,因此這會給您帶來錯誤,并顯示類似以下內容::
Data truncated for column 'model_id' at row 1
我們現在需要 model_id 欄位來支持我們的新 UUID,它的型別是 CHAR (36),別擔心!Laravel 讓這件事變得超級簡單,你不需要手動做這件事,只需將遷移更改為:
public function up()
{
Schema::create('some_package_table', function (Blueprint $table)
{
$table->bigIncrements('id');
$table->uuidMorphs('model');
...
}
}
更多PHP內容請訪問:
騰訊T3-T4標準精品PHP架構師教程目錄大全,只要你看完保證薪資上升一個臺階(持續更新)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/33656.html
標籤:PHP
上一篇:php Session方法實體
下一篇:PHP八種資料型別+使用實體
