Ответ 1
По версия 2.3 вы можете просто добавить следующие аннотации к свойству:
/**
* @ORM\Column(type="guid")
* @ORM\Id
* @ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
Я хочу создать уникальный билет для моих билетов. Но как позволить доктрине генерировать уникальный идентификатор?
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
немного больше объясните:
По версия 2.3 вы можете просто добавить следующие аннотации к свойству:
/**
* @ORM\Column(type="guid")
* @ORM\Id
* @ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
Используйте собственную стратегию 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 :(');
}
}
}
}
Вы можете использовать аннотацию 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")
Doctrine будет рассматривать это поле как ваш первичный ключ (из-за аннотации @Id
), поэтому это поле уже уникально. Если у вас есть @GeneratedValue
аннотация в AUTO
, стратегия Doctrine определит, какую стратегию использовать зависимость от платформы db. Он по умолчанию будет IDENTITY
на MySql, и тогда поле будет auto_increment
.
Вы можете написать аннотацию id без скобок следующим образом.
Пока я поддерживаю подход UUID, предложенный Jonhathan, вы можете предпочесть более короткий, более читаемый идентификатор. В этом случае вы можете использовать ShortId Doctrine bundle.