如何在Symfony 4中生成唯一的ID?

5

我想创建一个唯一的ID,所以在我的 Controller.php 中,我写下了以下代码:

use Symfony\Component\Validator\Constraints\Uuid;

后来在我的函数中:

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

但我收到了以下错误信息:

尝试调用类 "Symfony\Component\Validator\Constraints\Uuid" 中未定义的方法 "uuid4"。


1
uniqid() PHP函数不适合使用吗?http://php.net/manual/fr/function.uniqid.php - acucchieri
3
Symfony 没有自带的 Uuid 生成器。约束条件只是检查一个有效的 uuid。你需要加载第三方生成器。有几个可用的选择。仔细阅读您获得 Uuid::uuid4() 行的位置。它可能会提到安装特定的软件包。而且,uniqid 不等同于 uuid。 - Cerad
1
但是uniqid()不安全。它基于当前时间。 - peace_love
1
你需要这个 $unique_id 是为了什么目的? - Fabian Schmick
2
如果您想要符合RFC4122标准的UUID,可以使用https://github.com/ramsey/uuid。 - acucchieri
3个回答

15

你可以从 https://packagist.org/packages/ramsey/uuid 使用 ramsey/uuid

composer require ramsey/uuid
安装完成后:
use Ramsey\Uuid\Uuid;

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

您可以查阅文档以获得更多信息。


谢谢!但是我收到了错误信息 尝试从命名空间“App\Controller”调用函数“generateUid”。 - peace_love
3
为使用该功能,您需要添加use Ramsey\Uuid\Uuid;并直接调用以下代码: $unique_id = $this->uuid = Uuid::uuid4(); 然后使用它。 - wanna know

9

只有Doctrine在将对象持久化到数据库时才能自动生成UUID。您可以在实体中设置如下:

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

有时候这确实是个问题,当你需要立即获取uuid以便在代码中进行进一步操作时,但此时你无法将对象持久化。因此我使用了这个包并取得了良好的经验:

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
        }
    }
}

1
要更新此答案,Doctrine UUID 策略现已弃用(2021)。请改用 ramsey/uuid。 - adxl

0
如果您向一个实体添加一个字段并需要该字段的自动生成 UUID,并且已经有自动生成的自增 ID,则可以在持久化实体之前进行生成。
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();
}

此外,你可能需要修改迁移

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

这里是关于为什么使用注释进行多个自动生成无法与Doctrine一起工作的解释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接