Ідентифікатори сутностей

← Ідентифікатори сутностей

Ashterix

docs: Doctrine section with Doctrine Behaviors and Doctrine Helper (uk + en)

uk/docs/doctrine/doctrine-helper/entity_ids.md новий файл +149 −0

Ідентифікатори сутностей

Трейти з Ufo\DoctrineHelper\Traits додають у сутність властивість protected $id з атрибутами #[ORM\Id] і #[ORM\Column] та метод getId(). Решту мапінгу сутності (#[ORM\Entity], таблиця, інші поля) ви описуєте як завжди.

Трейт Колонка Генерація getId()
AutoIncrementIdTrait INTEGER, unsigned базою даних (#[ORM\GeneratedValue]) ?int
UuidIdTrait string(36), unique у коді: generateUniqueId() → UUID v7 string
UniqueIdTrait string(13), unique у коді: generateUniqueId() → uniqid() string
UniqueUuidIdTrait (застарілий) string(36), unique як у UuidIdTrait string

AutoIncrementIdTrait

use Doctrine\ORM\Mapping as ORM;
use Ufo\DoctrineHelper\Traits\AutoIncrementIdTrait;

#[ORM\Entity]
class Customer
{
    use AutoIncrementIdTrait;
}

Трейт оголошує:

#[ORM\Id]
#[ORM\Column(type: Types::INTEGER, options: ['unsigned' => true])]
#[ORM\GeneratedValue]
protected ?int $id = null;

Значення з'являється після flush(); до того getId() повертає null.

Не поєднуйте трейт з інтерфейсом IHaveAutoincrementId: getId(): ?int трейту несумісний з getId(): int інтерфейсу, і PHP завершується з fatal error. Деталі й обхідний шлях — у Відомих помилках.

UuidIdTrait

#[ORM\Id]
#[ORM\Column(type: Types::STRING, length: 36, unique: true)]
#[ORM\GeneratedValue(strategy: 'NONE')]
protected string $id;

Doctrine не генерує значення (strategy: 'NONE'), тому ідентифікатор задає сама сутність — зазвичай у конструкторі:

use Doctrine\ORM\Mapping as ORM;
use Ufo\DoctrineHelper\Interfaces\IHaveUniqueUuid;
use Ufo\DoctrineHelper\Traits\UuidIdTrait;

#[ORM\Entity]
class Order implements IHaveUniqueUuid
{
    use UuidIdTrait;

    public function __construct()
    {
        $this->generateUniqueId();   // напр. 01a155a4-36cd-7341-9406-48aa6d401e53
    }
}

Методи трейту:

  • protected generateUniqueId(): void — записує в $id новий UUID v7 (Uuid::generate()). UUID v7 впорядковані за часом створення, тож добре працюють як первинний ключ з індексом.
  • public getId(): string.
  • public static uniqueIdFromString(string $string): string — детермінований UUID v3 з рядка (Uuid::hash()): той самий рядок завжди дає той самий ідентифікатор.

Детермінований ідентифікатор зручний, коли сутність однозначно визначається природним ключем:

#[ORM\Entity]
class Tag implements IHaveUniqueUuid
{
    use UuidIdTrait;

    #[ORM\Column]
    private string $name;

    public function __construct(string $name)
    {
        $this->id = self::uniqueIdFromString($name);
        $this->name = $name;
    }
}

Якщо не викликати generateUniqueId() і не присвоїти $id, властивість лишиться неініціалізованою, і getId() чи persist() завершаться помилкою.

UniqueIdTrait

Той самий підхід, але ідентифікатор — результат uniqid(): 13 шістнадцяткових символів (string(13), unique), напр. 6ad66fabb1662.

use Ufo\DoctrineHelper\Traits\UniqueIdTrait;

#[ORM\Entity]
class Session
{
    use UniqueIdTrait;

    public function __construct()
    {
        $this->generateUniqueId();
    }
}

uniqid() будується з поточного часу в мікросекундах і не гарантує унікальності, якщо ідентифікатори створюються паралельно в кількох процесах. Там, де це важливо, беріть UuidIdTrait. Методу uniqueIdFromString() цей трейт не має.

UniqueUuidIdTrait

Позначений @deprecated Use UuidIdTrait instead. Відрізняється від UuidIdTrait лише тим, що не має атрибута #[ORM\GeneratedValue] (для #[ORM\Id] без нього Doctrine теж не генерує значення). Заміна — зміна одного рядка use.

Інтерфейси

Інтерфейс Метод Сумісні трейти
IHaveUniqueUuid getId(): string UuidIdTrait, UniqueIdTrait, UniqueUuidIdTrait
IHaveAutoincrementId getId(): int жоден (див. попередження вище)

Інтерфейси дають змогу типізувати код, що працює з будь-якою сутністю певного виду ключа, без прив'язки до конкретного класу:

use Ufo\DoctrineHelper\Interfaces\IHaveUniqueUuid;

function cacheKey(IHaveUniqueUuid $entity): string
{
    return $entity::class . ':' . $entity->getId();
}

Uuid

Ufo\DoctrineHelper\Utils\Uuid — обгортка над ramsey/uuid, яку використовують трейти. Її можна викликати й напряму:

use Ufo\DoctrineHelper\Utils\Uuid;

Uuid::generate();        // новий UUID v7
Uuid::hash('test');      // UUID v3 у просторі імен OID: завжди 61df151d-7508-321d-ada6-27936752b809

До 1.1.0 Uuid::generate() повертав UUID v4 (див. Історію змін).