web-dev-qa-db-fra.com

Générer un identifiant unique - doctrine - symfony2

Je souhaite générer un identifiant de ticket unique pour mes tickets. Mais comment laisser doctrine générer un identifiant unique?

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

un peu plus expliquer:

  • id doit être 6 chartes comme: 678915
  • l'identifiant doit être unique
37
Mitchel Verschoof

Depuis version 2. , vous pouvez simplement ajouter les annotations suivantes à votre propriété:

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

Utilisez une stratégie GeneratedValue personnalisée:

1. Dans votre classe Entity:

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

2. Puis créez le fichier AppBundle/Doctrine/RandomIdGenerator.php avec contenu

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 :(');
            }  
        }

    }
}
38
psylosss

Vous pouvez utiliser l'annotation PrePersist, comme ceci:

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

Comme le nom de l'annotation le suggère, il sera exécuté avant la persistance de l'objet dans la base de données.

Pour un identifiant unique, j'utilise simplement une fonction php uniqid () native http://php.net/manual/en/function.uniqid.php qui renverra 13 caractères. Pour obtenir seulement 6 caractères, reportez-vous à ceci Génération d'ID de ticket PHP

Dans la propriété $ id, je pense que vous devez également supprimer cette ligne pour empêcher sa valeur générée automatiquement:

@ORM\GeneratedValue(strategy="AUTO")
3
ihsan

Pendant que j'appuie l'approche UUID suggérée par Jonhathan, vous pourriez préférer un identifiant plus court et plus lisible. Dans ce cas, vous pouvez utiliser ShortId Doctrine bundle .

1
Massimiliano Arione

Doctrine traitera ce champ comme votre clé primaire (en raison du @Id annotation), ce champ est donc déjà unique. Si vous avez le @GeneratedValue annotation sur AUTO stratégie Doctrine déterminera la stratégie à utiliser en fonction de la plate-forme db. Elle sera par défaut à IDENTITY sur MySql et le champ affichera être un auto_increment puis.

Vous pouvez écrire l'annotation id sans les crochets comme suit.

  • ORM\Id
1
Bram Gerritsen