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




php reserved (5)

Vous pouvez utiliser l'annotation PrePersist, comme ceci:

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

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

Pour l'identifiant unique, j'utilise simplement une fonction native php uniqid () http://php.net/manual/en/function.uniqid.php qui retournera 13 caractères. Pour obtenir seulement 6 caractères, référez-vous à cette 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")

Je souhaite générer un ID de ticket unique pour mes tickets. Mais comment laisser la 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
  • id doit être unique

À partir de la version 2.3 , vous pouvez simplement ajouter les annotations suivantes à votre propriété:

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

Utilisez la stratégie personnalisée GeneratedValue:

1. Dans votre classe Entity:

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

2. Créez ensuite le fichier AppBundle/Doctrine/RandomIdGenerator.php avec le 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);

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

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

    }
}

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


Pas techniquement lié à votre problème. Cependant, j'ai eu beaucoup de mal à résoudre le problème de "Serialization of 'Closure' n'est pas autorisé" lors de l'utilisation de PHPUnit, et cette question est le meilleur résultat de Google.

Le problème vient du fait que PHPUnit sérialise tous les $ GLOBALS dans le système pour les sauvegarder pendant que le test est en cours. Il les restaure ensuite une fois le test terminé.

Cependant, si vous avez des fermetures dans votre espace GLOBAL, cela va causer des problèmes. Il y a deux façons de le résoudre.

Vous pouvez désactiver totalement la procédure de sauvegarde globale en utilisant une annotation.

/**
 * @backupGlobals disabled
 */
class MyTest extends PHPUnit_Framework_TestCase
{
    // ...
}

Ou, si vous savez quelle variable est à l'origine du problème (recherchez un lambda dans var_dump ($ GLOBALS)), vous pouvez simplement mettre en liste noire la ou les variables du problème.

class MyTest extends PHPUnit_Framework_TestCase
{
    protected $backupGlobalsBlacklist = array('application');
    // ...
}




symfony doctrine