PHP和Doctrine:如何创建唯一ID

时间:2016-11-03 11:30:28

标签: php mysql symfony doctrine-orm doctrine

我想创建唯一的ID,例如interface

我已经使用了Doctrine的dujUSJue9389sjgjik策略来创建它们,但结果类似于UUID:我不喜欢破折号的使用我想要更短的ID。

他们必须识别一些实体来构建像d9c363ae-a1b7-11e6-a66d-9e9923e30d94这样的网址。

使用PHP http://example.com/entity/hduicw43tv43bic并不能保证生成的值的唯一性。我认为冲突是非常罕见的,但是,无论如何,根本没有被排除在外,所以我不考虑它"安全" (冲突可能会导致异常,并且行创建可能会导致很多问题需要解决)。

所以,使用Doctrine和Symfony,我正在寻找一种方法来生成像uniqid()这样的值,并检查它的唯一性。如果它已经存在,则必须生成新值。一旦实体具有唯一值,就可以保留它。生成应该在创建实体时发生。

关于如何实现这一点的任何想法?

4 个答案:

答案 0 :(得分:3)

所以,混合@Jakub Matczak建议的answer by @Matteoanswer by psyloss我想出了这个:

class Company
{
    /**
     * @var string
     *
     * @ORM\Column(name="id", type="string")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\IdGenerator")
     */
     private $id;

     ...

然后

namespace AppBundle\Doctrine;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Ramsey\Uuid\Uuid;

/**
 * {@inheritdoc}
 */
class IdGenerator extends AbstractIdGenerator
{
    /**
     * {@inheritdoc}
     */
    public function generate(EntityManager $em, $entity)
    {
        $uuid = Uuid::uuid4()->getHex();

        if (null !== $em->getRepository(get_class($entity))->findOneBy(['id' => $uuid])) {
            $uuid = $this->generate($em, $entity);
        }

        return $uuid;
    }
}

此生成器还检查具有相同名称的现有实体,如果需要,重新生成UUID并保证唯一性。

生成的值正是我想要的:7b165049eb224f548021f68caefc57f6

答案 1 :(得分:1)

如果Doctrine的UUID策略很好,你可以简单地改变它:

$in = 'd9c363ae-a1b7-11e6-a66d-9e9923e30d94';
$out = base_convert(strtr($in,'-',''),16,36);
print_r($out);

简短,没有破折号,可反转

答案 2 :(得分:1)

我建议您使用ramsey-uuid库,广告使用如下:

$uuid = \Ramsey\Uuid\Uuid::uuid4();
echo $uuid->getHex();

或者,如果您已经拥有UUID,则可以执行以下操作:

$uuid = \Ramsey\Uuid\Uuid::fromString('f6a1fd62-1445-42fc-9e7b-d8c6e9da33a1');
echo $uuid->getHex();

更多信息in this article

希望这个帮助

答案 3 :(得分:0)

Ramsey uuid lib是奥赫的良好开端。还有一个来自安东尼https://github.com/ircmaxell/RandomLib的图书馆。

但要注意uuid,它们可能会损坏您的数据!此外,您无法通过选择检查ID是否已在数据库中。如果两个用户同时创建2条记录,则可以获得相同的ID。