symfony体系结构:在实体创建时具有存储库访问权限的自定义方法

时间:2013-10-16 09:11:01

标签: php symfony

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

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

我看到的问题是symfony中的我无法从实体类中访问存储库,因此我无法使用lifecycle callback。我理解这背后的原因。另一方面,哈希生成与控制器无关 - 对我而言,它是属于模型的内部逻辑。如果我以后更改数据结构,我需要编辑控制器。

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

3 个答案:

答案 0 :(得分:1)

回答我自己的问题:

我创建了一个custom repository,可以访问教条实体管理器。

存储库有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不必关心哈希创建。

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

答案 1 :(得分:1)

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

答案 2 :(得分: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());
    }

    // ...

}

希望这有帮助