Подтвердить что ты не робот

Создание уникальной id-доктрины - symfony2

Я хочу создать уникальный билет для моих билетов. Но как позволить доктрине генерировать уникальный идентификатор?

/**
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id()
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

немного больше объясните:

  • id должен быть 6 чартеров: 678915
  • id должен быть уникальным
4b9b3361

Ответ 1

По версия 2.3 вы можете просто добавить следующие аннотации к свойству:

/**
 * @ORM\Column(type="guid")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="UUID")
 */
protected $id;

Ответ 2

Используйте собственную стратегию GeneratedValue:

1. В вашем классе Entity:

/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="CUSTOM")
 * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\RandomIdGenerator")
 */
protected $id;

2. Затем создайте файл AppBundle/Doctrine/RandomIdGenerator.php с содержимым

namespace AppBundle\Doctrine;
use Doctrine\ORM\Id\AbstractIdGenerator;

class RandomIdGenerator extends AbstractIdGenerator
{
    public function generate(\Doctrine\ORM\EntityManager $em, $entity)
    {
        $entity_name = $em->getClassMetadata(get_class($entity))->getName();

        // Id must be 6 digits length, so range is 100000 - 999999
        $min_value = 100000;
        $max_value = 999999;

        $max_attempts = $min_value - $max_value;
        $attempt = 0;

        while (true) {
            $id = mt_rand($min_value, $max_value);
            $item = $em->find($entity_name, $id);

            // Look in scheduled entity insertions (persisted queue list), too
            if (!$item) {
                $persisted = $em->getUnitOfWork()->getScheduledEntityInsertions();
                $ids = array_map(function ($o) { return $o->getId(); }, $persisted);
                $item = array_search($id, $ids);
            }

            if (!$item) {
                return $id;
            }

            // Should we stop?
            $attempt++;
            if ($attempt > $max_attempts) {
                throw new \Exception('RandomIdGenerator worked hardly, but failed to generate unique ID :(');
            }  
        }

    }
}

Ответ 3

Вы можете использовать аннотацию PrePersist, например:

/**
 * @ORM\PrePersist()
 */
public function preSave() {
    $this->id = uniqid();
}

Как следует из названия аннотации, он будет запущен до сохранения объекта в базе данных.

Для уникального id я просто использую встроенную функцию php uniqid() http://php.net/manual/en/function.uniqid.php, которая вернет 13 символов. Чтобы получить только 6 символов, обратитесь к этому Генерированию идентификатора билета PHP

В свойстве $id, я думаю, вам также нужно удалить эту строку, чтобы предотвратить автоматически сгенерированное значение:

@ORM\GeneratedValue(strategy="AUTO")

Ответ 4

Doctrine будет рассматривать это поле как ваш первичный ключ (из-за аннотации @Id), поэтому это поле уже уникально. Если у вас есть @GeneratedValue аннотация в AUTO, стратегия Doctrine определит, какую стратегию использовать зависимость от платформы db. Он по умолчанию будет IDENTITY на MySql, и тогда поле будет auto_increment.

Вы можете написать аннотацию id без скобок следующим образом.

  • ORM\Id

Ответ 5

Пока я поддерживаю подход UUID, предложенный Jonhathan, вы можете предпочесть более короткий, более читаемый идентификатор. В этом случае вы можете использовать ShortId Doctrine bundle.