How can I generate an unique id in Symfony 4?
Asked Answered
G

3

5

I want to create a unique id, so in my Controller.php, I write this:

use Symfony\Component\Validator\Constraints\Uuid;

and later in my function:

$unique_id = $this->uuid = Uuid::uuid4();

But I get the error message:

Attempted to call an undefined method named "uuid4" of class "Symfony\Component\Validator\Constraints\Uuid".

Gruber answered 27/11, 2018 at 13:37 Comment(5)
the uniqid() php function is not suitable ? php.net/manual/fr/function.uniqid.phpLita
Symfony does not come with a Uuid generator. The constraint just checks for a valid uuid. You need to load a third party generator. There are several available. Read carefully wherever you got the Uuid::uuid4() line from. It probably talks about installing a specific package. And no, uniqid is not the same as a uuid.Haase
But uniqid() is not secure. It is based on the current time.Gruber
For which purpose you need this $unique_id ?Bunkhouse
If you want a RFC4122 compliant UUID, you can use github.com/ramsey/uuidLita
I
15

You can use ramsey/uuid from https://packagist.org/packages/ramsey/uuid

composer require ramsey/uuid

After the installation :

use Ramsey\Uuid\Uuid;

function generateUid()
{
   return Uuid::uuid4();
}

You can check the documentation for more informations.

Isauraisbel answered 27/11, 2018 at 14:4 Comment(2)
Thank you! But I get the error Attempted to call function "generateUid" from namespace "App\Controller".Gruber
To use the function you have to add use Ramsey\Uuid\Uuid; and directly call : $unique_id = $this->uuid = Uuid::uuid4(); and useIsauraisbel
M
9

Only doctrine can automatically generate uuid for you when persisting objects to database. You can set it up like this in your entity.

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

And this exactly is a problem sometimes, when you need the uuid immediately for further instructions in your code, but you could not persist the object at that point of time. So I made good experiences using this package:

https://packagist.org/packages/ramsey/uuid

<?php

namespace YourBundle\Controller;

use Ramsey\Uuid\Uuid;

/**
 * Your controller.
 *
 * @Route("/whatever")
 */
class YourController extends Controller
{
    /**
     * @Route("/your/route", name="your_route")
     */
    public function yourFunction(Request $request)
    {
        try {
            $uuidGenerator = Uuid::uuid4();
            $uuid = $uuidGenerator->toString();
        } catch (\Exception $exception) {
            // Do something
        }
    }
}
Maharaja answered 27/11, 2018 at 14:17 Comment(1)
To update this answer, the doctrine UUID strategy is now deprecated (2021). Use ramsey/uuid instead.Trimaran
K
0

If you add a field to an entity and need autogenerated UUID for that field and you already have autogenerated autoincrement Id then you can do generating before persisting an entity.

use Symfony\Component\Uid\Uuid;

// ...

/**
 * @var string
 *
 * @ORM\Column(name="uuid", type="guid", unique=true)
 */
private $uuid;

/**
 * @ORM\PrePersist()
 */
public function prePersist()
{
    $this->setDateCreated($this->getDateCreated() ?: (new DateTime()));
    $this->uuid = Uuid::v4()->toRfc4122();
}

Also, you may need to modify migrations

public function preUp(Schema $schema) : void
{
    $this->addSql('ALTER TABLE table_name ADD uuid CHAR(36) DEFAULT NULL COMMENT \'(DC2Type:guid)\'');
    $this->addSql('CREATE UNIQUE INDEX UNIQ_1C1B038BD17F50A6 ON table_name (uuid)');
}

public function up(Schema $schema) : void
{
    // this up() migration is auto-generated, please modify it to your needs
    $this->addSql('UPDATE table_name SET uuid = UUID()');
    $this->addSql('ALTER TABLE table_name CHANGE uuid uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:guid)\'');
}

public function down(Schema $schema) : void
{
    // this down() migration is auto-generated, please modify it to your needs
    $this->addSql('DROP INDEX UNIQ_1C1B038BD17F50A6 ON table_name');
    $this->addSql('ALTER TABLE table_name DROP uuid');
}

Here is an explanation of why more than one autogeneration thru annotations doesn't work with Doctrine

Kelm answered 12/5, 2021 at 2:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.