Что такое UUID?
UUID это универсальный уникальный идентификатор. 16-байтный (128-битный) номер, используемый для уникальной идентификации какого-либо объекта без общего центра координации. То есть мы самостоятельно генерируем UUID и уверены, что полученный идентификатор уникален. Общее количество уникальных ключей UUID составляет 2128 = 25616 или около 3,4 x 1038. Генерируя 1 триллион ключей каждую наносекунду, перебрать все возможные значения удастся лишь за 10 миллиардов лет. В шестнадцатеричной системе счисления UUID выглядит как:
9675e665-1923-4c6f-97c0-259b191fab24
Я не буду вдаваться в подробности плюсов и минусов UUID по сравнению с обычным автоматическим инкрементным идентификатором, про это есть отдельные статьи. Но я расскажу вам как можно использовать UUID в вашей Laravel.
Подготавливаем миграцию
Первым шагом использования UUID в вашей базе данных это настройка столбца идентификатора. По умолчанию в каждой миграция Laravel автоматически создается столбец $table->primary(‘id’);.
Использовать UUIDs так же просто, как обновить миграцию. Добавляем метод ->uuid(), доступный прямо из «коробки». Например миграция для сущности Post:
Schema::create('posts', function (Blueprint $table) { $table->uuid('id')->primary(); $table->string('title'); $table->text('body'); $table->timestamps(); });
Обратите внимание на строку: $table->uuid(‘id’)->primary();. Мы используем метод uuid() вместо обычного increments().
Создание UUID
Если вы запустите php artisan migrate и попытаетесь создать новую запись, через фабрику или вручную, то получите ошибку, утверждающую, что столбец id не может быть null.
При использовании метода primary() в миграциях Laravel понимает, что это автоинкрементный столбец, и создает его таким. Но, поскольку мы перешли на использование UUID, нам нужно создавать ID самостоятельно.
Используем события модели Eloquent
Раз мы работает с Laravel, то скорей всего используем и Eloquent для взаимодействия с базой данных.
Eloquent имеет так называемую Событийная модель (Model Events). В общей сложности он запускает 11 событий в разных сценариях:
- retrieved
- creating
- created
- updating
- updated
- saving
- saved
- deleting
- deleted
- restoring
- restored
Если вы хотите узнать о Событиях больше, то ознакомьтесь с документацией.
Вернемся к созданию UUID. Давайте посмотрим, как может выглядеть ваша модель Post:
class Post extends Model { protected $guarded = []; protected static function boot() { parent::boot(); static::creating(function ($post) { $post->{$post->getKeyName()} = (string) Str::uuid(); }); } public function getIncrementing() { return false; } public function getKeyType() { return 'string'; } }
Модель имеет 3 метода. В методе boot мы можем подключиться к нашей модели и прослушивать любые события Eloquent. Метод getIncrementing используется Eloquent, если идентификаторы в таблице инкрементны. Помните, мы используем UUID, поэтому устанавливаем false на автоинкремент. А метод getKeyType просто указывает, что идентификаторы в таблице должны храниться в виде строк.
В нашем методе boot мы ожидаем события creating. Оно запускается непосредственно перед тем, как запись сохраняется в базе данных. Мы подключаемся к этому событию и используем метод uuid(), предоставленный классом Str в Laravel.
Раньше, для генерации UUID необходимо было устанавливать дополнительный пакет через Composer, а сейчас это есть прямо в Laravel.
Обычно я делаю отдельный трейт (trait) под названием UsesUuid, где я храню логику, описанную выше. Это позволяет не повторять код для каждой модели, где нужно использовать UUID:
<?php namespace App\Models\Concerns; 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'; } }
Обратите внимание, что всё обобщенно и не привязано к отдельной модели.
Теперь в любой модели, вы можете просто использовать трейт UsesUuid следующим образом:
class Post extends Model { use App\Models\Concerns\UsesUuid; protected $guarded = []; }
Вот и все. Всего за несколько простых шагов вы получили UUID для Laravel.
Автор: Wilbur Powery
Перевод: Алексей Широков
Наш Телеграм-канал — следите за новостями о Laravel.