1

我有一个带有 UNIQUE 列的 DB 表,该列应该包含一个唯一的 8 个字符的字母数字字符串。

我(终于)从我自己的 MVC 框架迁移到了 symfony。到目前为止,我在 CREATE 上调用的模型中有一个私有方法。该方法中的循环将生成一个随机散列,并对表执行 READ 以查看它是否唯一:如果是,则将返回散列并注入 CREATE 请求。

我看到的问题是,在 symfony 中我无法从实体类中访问存储库,所以我不能使用生命周期回调。我理解这背后的原因。另一方面,哈希生成与控制器无关——对我来说,它是属于模型的内部逻辑。如果我以后更改数据结构,我需要编辑控制器。

我的问题是:在架构方面,我应该把哈希生成方法放在哪里?

4

3 回答 3

1

回答我自己的问题:

我创建了一个自定义存储库,它可以访问学说实体管理器。

存储库有一个createNewHash方法:

class HashRepository extends EntityRepository
{
    public function createNewHash()
    {
        $hash = new Hash();
        $hash->setHash($this->_getUniqueHash());
        $em = $this->getEntityManager();
        $em->persist($hash);
        $em->flush();
        return $hash;
    }

    private function _getUniqueHash()
    {
        $hash = null;
        $hashexists = true;
        while ($hashexists) {
            $hash = $this->_generateRandomAlphaNumericString();
            if (!$hashobject = $this->findOneByHash($hash)) {
                $hashexists = false;
            }
        }
        return $hash;
    }

    private function _generateRandomAlphaNumericString( $length=8 )
    {
        $bits = $length / 2;
        return bin2hex(openssl_random_pseudo_bytes($bits));
    }
}

然后可以从 Controller 调用该createNewHash()方法,并且 Controller 不必关心自己的哈希创建。

编辑:听众是另一种方式。

于 2013-10-16T10:16:28.320 回答
1

您可以使用监听器。您是对的,因为您需要访问存储库,所以生命周期回调不是正确的解决方案。但是您可以定义一个侦听器来侦听与生命周期回调相同的事件,但它是一项服务,因此可以将存储库作为依赖项。

于 2013-10-16T12:06:35.090 回答
0

在您的实体构造函数中,我可以添加以下内容:

<?php

namespace Acme\DemoBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MyEntity
 *
 * @ORM\Table(name="my_entity")
 */
class MyEntity
{
    /**
     * @ORM\Column(type="string", length=8, unique=true, nullable=false)
     * @var string
     */
    private $uniqId;

    public function __construct()
    {
        $this->uniqId = hash('crc32b', uniqid());
    }

    // ...

}

希望这可以帮助

于 2013-10-16T09:53:34.617 回答