2016-11-03 2 views
3

Я хотел бы создать уникальные идентификаторы, что-то вроде dujUSJue9389sjgjik.PHP и Doctrine: как создать уникальные идентификаторы

Я использовал стратегию Doctrine UUID, чтобы создать их, но в результате получилось что-то вроде d9c363ae-a1b7-11e6-a66d-9e9923e30d94: Мне не нравятся тире, а также я хотел бы иметь более короткие идентификаторы.

Им нужно идентифицировать некоторые объекты для создания URL-адреса, например http://example.com/entity/hduicw43tv43bic.

Использование PHP uniqid() не гарантирует уникальность сгенерированного значения. Я думаю, что конфликт очень редок, но, во всяком случае, не исключается вообще, поэтому я не рассматриваю его как «безопасный» (конфликт может вызвать исключение, а создание строк может вызвать много головной боли для исправления).

Итак, используя Doctrine и Symfony, я ищу способ генерировать значение, например ajybUYBD74883bj8d74NJ, и проверить его уникальность. Если он уже присутствует, необходимо создать новое значение. Когда объект имеет уникальное значение, он может быть сохранен. Генерация должна произойти, когда объект создается.

Любые идеи о том, как реализовать это?

+0

Не существует реального уникального алгоритма генерации значений, который гарантирует уникальность, включая UUID/GUID. –

+0

Да, я знаю об этом. Для этого я ищу процедуру проверки уникальности и сбоя (сгенерированный идентификатор уже существует) регенерирует его.Это должно быть сделано в сущности Doctrine. – Aerendir

+1

Это должно быть сделано в самом сущности. Это не задача сущности проверять другие объекты (включая репозиторий вызовов). Это должно быть работа генератора ID. Вы можете попытаться создать собственный генератор идентификаторов, но я не могу найти документацию об этом. Во всяком случае, вот пример в ответе psylosss: http://stackoverflow.com/questions/15039665/generate-unique-id-doctrine-symfony2 –

ответ

1

Так, смешав answer by @Matteo и answer by psyloss предложил @Jakub Matczak я пришел с этим:

class Company 
{ 
    /** 
    * @var string 
    * 
    * @ORM\Column(name="id", type="string") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="CUSTOM") 
    * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\IdGenerator") 
    */ 
    private $id; 

    ... 

, а затем

namespace AppBundle\Doctrine; 

use Doctrine\ORM\EntityManager; 
use Doctrine\ORM\Id\AbstractIdGenerator; 
use Ramsey\Uuid\Uuid; 

/** 
* {@inheritdoc} 
*/ 
class IdGenerator extends AbstractIdGenerator 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function generate(EntityManager $em, $entity) 
    { 
     $uuid = Uuid::uuid4()->getHex(); 

     if (null !== $em->getRepository(get_class($entity))->findOneBy(['id' => $uuid])) { 
      $uuid = $this->generate($em, $entity); 
     } 

     return $uuid; 
    } 
} 

Этот генератор также проверяет для существующего объекта с тем же имя, регенерируя UUID, если это необходимо, и гарантируя уникальность.

Сгенерированное значение - именно то, что я хочу: 7b165049eb224f548021f68caefc57f6.

1

Если стратегия UUID доктрина является хорошим вы можете просто преобразовать, что:

$in = 'd9c363ae-a1b7-11e6-a66d-9e9923e30d94'; 
$out = base_convert(strtr($in,'-',''),16,36); 
print_r($out); 

короткий, не прочерк, reverseable

1

Я предлагаю вам использовать ramsey-uuid библиотеку, объявления Использование следующим образом:

$uuid = \Ramsey\Uuid\Uuid::uuid4(); 
echo $uuid->getHex(); 

В качестве альтернативы, если у вас уже есть UUID, вы можете сделать это:

$uuid = \Ramsey\Uuid\Uuid::fromString('f6a1fd62-1445-42fc-9e7b-d8c6e9da33a1'); 
echo $uuid->getHex(); 

Подробнее in this article

Надеется, что это поможет

0

Рэмси UUID Lib является Auch хорошей стартовой точкой. Существует также библиотека от anthony https://github.com/ircmaxell/RandomLib.

Но заботитесь о uuid, они могут испортить ваши данные! Также вы не можете проверить с помощью select, если идентификатор уже находится в БД. Если два пользователя одновременно создадут 2 записи, они смогут получить один и тот же идентификатор.

+0

Почему я не могу проверить, находится ли идентификатор уже в БД? – Aerendir