我想创建唯一的ID,例如interface
。
我已经使用了Doctrine的dujUSJue9389sjgjik
策略来创建它们,但结果类似于UUID
:我不喜欢破折号的使用我想要更短的ID。
他们必须识别一些实体来构建像d9c363ae-a1b7-11e6-a66d-9e9923e30d94
这样的网址。
使用PHP http://example.com/entity/hduicw43tv43bic
并不能保证生成的值的唯一性。我认为冲突是非常罕见的,但是,无论如何,根本没有被排除在外,所以我不考虑它"安全" (冲突可能会导致异常,并且行创建可能会导致很多问题需要解决)。
所以,使用Doctrine和Symfony,我正在寻找一种方法来生成像uniqid()
这样的值,并检查它的唯一性。如果它已经存在,则必须生成新值。一旦实体具有唯一值,就可以保留它。生成应该在创建实体时发生。
关于如何实现这一点的任何想法?
答案 0 :(得分:3)
所以,混合@Jakub Matczak建议的answer by @Matteo和answer 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。