docs: Doctrine section with Doctrine Behaviors and Doctrine Helper (uk + en)
en/docs/doctrine/doctrine-helper/entity_ids.md
new file +149
ā0
1
+
# Entity identifiers
2
+
3
+
The traits in `Ufo\DoctrineHelper\Traits` add a `protected $id` property with the `#[ORM\Id]` and `#[ORM\Column]` attributes and a `getId()` method to an entity. The rest of the entity mapping (`#[ORM\Entity]`, table, other fields) is described as usual.
4
+
5
+
| Trait | Column | Generation | `getId()` |
6
+
|-------|--------|------------|-----------|
7
+
| `AutoIncrementIdTrait` | `INTEGER`, unsigned | by the database (`#[ORM\GeneratedValue]`) | `?int` |
8
+
| `UuidIdTrait` | `string(36)`, unique | in code: `generateUniqueId()` ā UUID v7 | `string` |
9
+
| `UniqueIdTrait` | `string(13)`, unique | in code: `generateUniqueId()` ā `uniqid()` | `string` |
10
+
| `UniqueUuidIdTrait` (deprecated) | `string(36)`, unique | as in `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
+
The trait declares:
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
+
The value appears after `flush()`; until then `getId()` returns `null`.
35
+
36
+
:::warning
37
+
Do not combine the trait with the `IHaveAutoincrementId` interface: the trait's `getId(): ?int` is incompatible with the interface's `getId(): int`, and PHP stops with a fatal error. Details and a workaround are in [Known issues](/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 does not generate the value (`strategy: 'NONE'`), so the entity sets its own identifier, usually in the constructor:
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(); // e.g. 01a155a4-36cd-7341-9406-48aa6d401e53
64
+
}
65
+
}
66
+
```
67
+
68
+
Trait methods:
69
+
70
+
* `protected generateUniqueId(): void` ā writes a new UUID v7 (`Uuid::generate()`) to `$id`. UUID v7 values are ordered by creation time, so they work well as an indexed primary key.
71
+
* `public getId(): string`.
72
+
* `public static uniqueIdFromString(string $string): string` ā a deterministic UUID v3 from a string (`Uuid::hash()`): the same string always gives the same identifier.
73
+
74
+
A deterministic identifier is handy when an entity is uniquely defined by a natural key:
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
+
If you neither call `generateUniqueId()` nor assign `$id`, the property stays uninitialized, and `getId()` or `persist()` fail with an error.
94
+
95
+
## UniqueIdTrait
96
+
97
+
The same approach, but the identifier is the result of `uniqid()`: 13 hexadecimal characters (`string(13)`, unique), e.g. `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()` is built from the current time in microseconds and does not guarantee uniqueness when identifiers are created in parallel by several processes. Where that matters, use `UuidIdTrait`. This trait has no `uniqueIdFromString()` method.
115
+
116
+
## UniqueUuidIdTrait
117
+
118
+
Marked `@deprecated Use UuidIdTrait instead`. It differs from `UuidIdTrait` only in lacking the `#[ORM\GeneratedValue]` attribute (for `#[ORM\Id]` without it Doctrine does not generate the value either). Switching is a one-line `use` change.
119
+
120
+
## Interfaces
121
+
122
+
| Interface | Method | Compatible traits |
123
+
|-----------|--------|-------------------|
124
+
| `IHaveUniqueUuid` | `getId(): string` | `UuidIdTrait`, `UniqueIdTrait`, `UniqueUuidIdTrait` |
125
+
| `IHaveAutoincrementId` | `getId(): int` | none (see the warning above) |
126
+
127
+
The interfaces let you type code that works with any entity of a given key kind without binding it to a concrete class:
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` is a wrapper over `ramsey/uuid` used by the traits. It can also be called directly:
141
+
142
+
```php
143
+
use Ufo\DoctrineHelper\Utils\Uuid;
144
+
145
+
Uuid::generate(); // a new UUID v7
146
+
Uuid::hash('test'); // UUID v3 in the OID namespace: always 61df151d-7508-321d-ada6-27936752b809
147
+
```
148
+
149
+
Before 1.1.0 `Uuid::generate()` returned a UUID v4 (see the [Changelog](/docs/doctrine/doctrine-helper/change_log)).