docs: Doctrine section with Doctrine Behaviors and Doctrine Helper (uk + en)
uk/docs/doctrine/doctrine-helper/entity_ids.md
новий файл +149
−0
1
+
# Ідентифікатори сутностей
2
+
3
+
Трейти з `Ufo\DoctrineHelper\Traits` додають у сутність властивість `protected $id` з атрибутами `#[ORM\Id]` і `#[ORM\Column]` та метод `getId()`. Решту мапінгу сутності (`#[ORM\Entity]`, таблиця, інші поля) ви описуєте як завжди.
4
+
5
+
| Трейт | Колонка | Генерація | `getId()` |
6
+
|-------|---------|-----------|-----------|
7
+
| `AutoIncrementIdTrait` | `INTEGER`, unsigned | базою даних (`#[ORM\GeneratedValue]`) | `?int` |
8
+
| `UuidIdTrait` | `string(36)`, unique | у коді: `generateUniqueId()` → UUID v7 | `string` |
9
+
| `UniqueIdTrait` | `string(13)`, unique | у коді: `generateUniqueId()` → `uniqid()` | `string` |
10
+
| `UniqueUuidIdTrait` (застарілий) | `string(36)`, unique | як у `UuidIdTrait` | `string` |
11
+
12
+
## AutoIncrementIdTrait
13
+
14
+
```php
15
+
use Doctrine\ORM\Mapping as ORM;
16
+
use Ufo\DoctrineHelper\Traits\AutoIncrementIdTrait;
17
+
18
+
#[ORM\Entity]
19
+
class Customer
20
+
{
21
+
use AutoIncrementIdTrait;
22
+
}
23
+
```
24
+
25
+
Трейт оголошує:
26
+
27
+
```php
28
+
#[ORM\Id]
29
+
#[ORM\Column(type: Types::INTEGER, options: ['unsigned' => true])]
30
+
#[ORM\GeneratedValue]
31
+
protected ?int $id = null;
32
+
```
33
+
34
+
Значення з'являється після `flush()`; до того `getId()` повертає `null`.
35
+
36
+
:::warning
37
+
Не поєднуйте трейт з інтерфейсом `IHaveAutoincrementId`: `getId(): ?int` трейту несумісний з `getId(): int` інтерфейсу, і PHP завершується з fatal error. Деталі й обхідний шлях — у [Відомих помилках](/docs/doctrine/doctrine-helper/known_issues/open).
38
+
:::
39
+
40
+
## UuidIdTrait
41
+
42
+
```php
43
+
#[ORM\Id]
44
+
#[ORM\Column(type: Types::STRING, length: 36, unique: true)]
45
+
#[ORM\GeneratedValue(strategy: 'NONE')]
46
+
protected string $id;
47
+
```
48
+
49
+
Doctrine не генерує значення (`strategy: 'NONE'`), тому ідентифікатор задає сама сутність — зазвичай у конструкторі:
50
+
51
+
```php
52
+
use Doctrine\ORM\Mapping as ORM;
53
+
use Ufo\DoctrineHelper\Interfaces\IHaveUniqueUuid;
54
+
use Ufo\DoctrineHelper\Traits\UuidIdTrait;
55
+
56
+
#[ORM\Entity]
57
+
class Order implements IHaveUniqueUuid
58
+
{
59
+
use UuidIdTrait;
60
+
61
+
public function __construct()
62
+
{
63
+
$this->generateUniqueId(); // напр. 01a155a4-36cd-7341-9406-48aa6d401e53
64
+
}
65
+
}
66
+
```
67
+
68
+
Методи трейту:
69
+
70
+
* `protected generateUniqueId(): void` — записує в `$id` новий UUID v7 (`Uuid::generate()`). UUID v7 впорядковані за часом створення, тож добре працюють як первинний ключ з індексом.
71
+
* `public getId(): string`.
72
+
* `public static uniqueIdFromString(string $string): string` — детермінований UUID v3 з рядка (`Uuid::hash()`): той самий рядок завжди дає той самий ідентифікатор.
73
+
74
+
Детермінований ідентифікатор зручний, коли сутність однозначно визначається природним ключем:
75
+
76
+
```php
77
+
#[ORM\Entity]
78
+
class Tag implements IHaveUniqueUuid
79
+
{
80
+
use UuidIdTrait;
81
+
82
+
#[ORM\Column]
83
+
private string $name;
84
+
85
+
public function __construct(string $name)
86
+
{
87
+
$this->id = self::uniqueIdFromString($name);
88
+
$this->name = $name;
89
+
}
90
+
}
91
+
```
92
+
93
+
Якщо не викликати `generateUniqueId()` і не присвоїти `$id`, властивість лишиться неініціалізованою, і `getId()` чи `persist()` завершаться помилкою.
94
+
95
+
## UniqueIdTrait
96
+
97
+
Той самий підхід, але ідентифікатор — результат `uniqid()`: 13 шістнадцяткових символів (`string(13)`, unique), напр. `6ad66fabb1662`.
98
+
99
+
```php
100
+
use Ufo\DoctrineHelper\Traits\UniqueIdTrait;
101
+
102
+
#[ORM\Entity]
103
+
class Session
104
+
{
105
+
use UniqueIdTrait;
106
+
107
+
public function __construct()
108
+
{
109
+
$this->generateUniqueId();
110
+
}
111
+
}
112
+
```
113
+
114
+
`uniqid()` будується з поточного часу в мікросекундах і не гарантує унікальності, якщо ідентифікатори створюються паралельно в кількох процесах. Там, де це важливо, беріть `UuidIdTrait`. Методу `uniqueIdFromString()` цей трейт не має.
115
+
116
+
## UniqueUuidIdTrait
117
+
118
+
Позначений `@deprecated Use UuidIdTrait instead`. Відрізняється від `UuidIdTrait` лише тим, що не має атрибута `#[ORM\GeneratedValue]` (для `#[ORM\Id]` без нього Doctrine теж не генерує значення). Заміна — зміна одного рядка `use`.
119
+
120
+
## Інтерфейси
121
+
122
+
| Інтерфейс | Метод | Сумісні трейти |
123
+
|-----------|-------|----------------|
124
+
| `IHaveUniqueUuid` | `getId(): string` | `UuidIdTrait`, `UniqueIdTrait`, `UniqueUuidIdTrait` |
125
+
| `IHaveAutoincrementId` | `getId(): int` | жоден (див. попередження вище) |
126
+
127
+
Інтерфейси дають змогу типізувати код, що працює з будь-якою сутністю певного виду ключа, без прив'язки до конкретного класу:
128
+
129
+
```php
130
+
use Ufo\DoctrineHelper\Interfaces\IHaveUniqueUuid;
131
+
132
+
function cacheKey(IHaveUniqueUuid $entity): string
133
+
{
134
+
return $entity::class . ':' . $entity->getId();
135
+
}
136
+
```
137
+
138
+
## Uuid
139
+
140
+
`Ufo\DoctrineHelper\Utils\Uuid` — обгортка над `ramsey/uuid`, яку використовують трейти. Її можна викликати й напряму:
141
+
142
+
```php
143
+
use Ufo\DoctrineHelper\Utils\Uuid;
144
+
145
+
Uuid::generate(); // новий UUID v7
146
+
Uuid::hash('test'); // UUID v3 у просторі імен OID: завжди 61df151d-7508-321d-ada6-27936752b809
147
+
```
148
+
149
+
До 1.1.0 `Uuid::generate()` повертав UUID v4 (див. [Історію змін](/docs/doctrine/doctrine-helper/change_log)).