Даёт ли привязка функции uniqid к времени одинаковые результаты?

<blockquote>Функция не гарантирует уникальность значения, поскольку основывает значение на текущем времени в микросекундах или на текущем времени</blockquote> <br/> <br/> Верно ли я понимаю, что при одновременном использовании этой функции в разных местах будет получено одинаковое значение? <br/> <br/> Кроме того, существуют ли какие-то недокументированные нюансы, которыми можно поделиться? <br/> p.p.s. Если ответ «ДА», есть ли возможность воспроизвести этот сценарий?
  • 27 марта 2025 г. 13:25
Ответы на вопрос 2
Функция `uniqid()` в PHP генерирует уникальный идентификатор на основе текущего времени в микросекундах. Если вы используете `uniqid()` без второго параметра, то она генерирует строку, которая включает текущее время с точностью до миллисекунды. Это значит, что если два вызова `uniqid()` происходят в одно и то же время (в пределах одной миллисекунды), они могут возвращать одинаковое значение.

### Условия, при которых может возникнуть дублирование:

1. **Время вызова**: Если два процесса (или потока) выполняются одновременно и вызывают `uniqid()` в пределах одной и той же миллисекунды, они могут получить одно и то же значение.
   
2. **Отсутствие дополнительного параметра**: Если вы используете `uniqid()` без второго параметра, то, по сути, уникальность ограничивается временем, что приводит к риску коллизий.

### Есть ли возможность воспроизвести сценарий? 

Да, можно воспроизвести этот сценарий, например, с использованием параллельных запросов в веб-приложении или в многопоточной среде. Например, если два скрипта запускаются одновременно и делают вызовы `uniqid()`, и если они выполняются с миллисекундной разницей, то можно получить одинаковые значения.

### Советы:

Чтобы минимизировать риск возникновения дубликатов, вы можете:

- Использовать второй параметр функции, в котором вы можете передать `true`. Это добавит случайный компонент, что значительно уменьшит вероятность дубликатов:
  ```php
  $id = uniqid('', true);
  ```

- Альтернативно, если вам нужна гарантированная уникальность, стоит использовать другие методы генерации идентификаторов, такие как UUID (Universally Unique Identifier) или библиотеку `random_bytes()` для создания уникальных строк.

### Недокументированные нюансы:

- При использовании `uniqid()` важно помнить, что процессор и методы синхронизации операционной системы могут влиять на точность временных меток, что может в некоторых случаях привести к малым задержкам между вызовами в параллельных средах.

- Даже с использованием `uniqid()` с `true` не существует 100% гарантии уникальности, так как это зависит от состояния системы и нагрузки, поэтому для критически важных случаев лучше использовать более надежные методы.
Результаты uniqid() вызванные в одну и ту же микросекунду на разных серверах дадут одинаковый результат. <br/> Для генерации уникальных идентификаторов без коллизий используйте UUIDv4 или UUIDv7 если будете хранить идентификаторы в БД. <br/> Из библиотек для работы с UUID стандарт де факто это <a href="https://github.com/ramsey/uuid" rel="nofollow">https://github.com/ramsey/uuid</a>
Похожие вопросы