I want to generate a unique ticket ID for my tickets. But how to let doctrine generate a unique id?
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id()
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
little more explain:
- id must be 6 charters like: 678915
- id must be unique
As of version 2.3, you can just add the following annotations to your property:
/**
* @ORM\Column(type="guid")
* @ORM\Id
* @ORM\GeneratedValue(strategy="UUID")
*/
protected $id;
Use custom GeneratedValue strategy:
1. In your Entity class:
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="AppBundle\Doctrine\RandomIdGenerator")
*/
protected $id;
2. Then create file AppBundle/Doctrine/RandomIdGenerator.php
with content
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);
if (!$item) {
return $id;
}
// Should we stop?
$attempt++;
if ($attempt > $max_attempts) {
throw new \Exception('RandomIdGenerator worked hardly, but failed to generate unique ID :(');
}
}
}
}
You can use the PrePersist annotation, like this:
/**
* @ORM\PrePersist()
*/
public function preSave() {
$this->id = uniqid();
}
As the annotation name suggest, it will be run before object persistence into database.
For unique id, I simply use a native php uniqid() function http://php.net/manual/en/function.uniqid.php which will return 13 characters. To get only 6 characters, refer to this PHP Ticket ID Generation
In the $id property, I think you also need to remove this line to prevent auto generated value of it:
@ORM\GeneratedValue(strategy="AUTO")
Doctrine will treat this field as your primary key (because of the @Id
annotation), so this field is already unique. If you have the @GeneratedValue
annotation on AUTO
strategy Doctrine will figure out which strategy to use dependend on the db platform. It will default to IDENTITY
on MySql and the field will be a auto_increment
then.
You can write the id annotation without the brackets as follows.
While I'm seconding the UUID approach suggested by Jonhathan, you could prefer a shorter, more readable, identifier. In this case you can use ShortId Doctrine bundle.