Zend Framework генерирует уникальную строку - PullRequest
5 голосов
/ 18 сентября 2011

Я хочу сгенерировать уникальную буквенно-цифровую строку длиной 4-6 символов для сохранения в дБ для каждой записи (пользователя).Поле db имеет уникальный индекс, поэтому попытка сохранить ранее существующую строку приводит к ошибке.Прямо сейчас я генерирую случайную строку и использую try-catch, поэтому при добавлении новой записи, если она выдает исключение, я генерирую другую случайную строку и пытаюсь сохранить снова, и код продолжает пытаться, пока она не добавит запись успешно.Все это решение не только выглядит тяжелым, но и уродливым, поэтому я хочу его изменить.Я заинтересован в элегантном решении, поэтому любая помощь / руководство приветствуется.

1 Ответ

6 голосов
/ 18 сентября 2011

С учетом информации:

  • идентификатор должен быть уникальным
  • идентификатор не должен быть числовым
  • идентификатор не должен представлять последовательный ряд
  • идентификатор не будет введен пользователем

Функция PHP uniqid - это именно то, что вам нужно. Хотя он возвращает шестнадцатеричное значение длиной 13 символов.


** Редактировать **

Да, uniqid вернет порядковый номер, но мы можем легко обойти это. Считайте этот код

class IDGenerator {
   //const BIT_MASK = '01110011';

   static public function generate() {

      $id = uniqid();

      $id = base_convert($id, 16, 2);
      $id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);

      $chunks = str_split($id, 8);
      //$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);

      $id = array();
      foreach ($chunks as $key => $chunk) {
         //$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
         if ($key & 1) {  // odd
            array_unshift($id, $chunk);
         } else {         // even
            array_push($id, $chunk);
         }
      }

      return base_convert(implode($id), 2, 36);
   }
}

echo IDGenerator::generate();

Что даст результаты, такие как

ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2

Поскольку ничего не добавлено или не изменено, кроме перемешивания битов, не должно быть никаких дублированных значений, и все кажется случайным. Вуаля!

** Обновление (2014-02-24) **

Я обновляю этот фрагмент кода с момента его публикации. Вы можете найти исправленную версию здесь

...