我有一个带有UNIQUE列的数据库表,该列应包含唯一的8个字符的字母数字字符串。
我(最终)从我自己的MVC框架转移到symfony。到目前为止,我在模型中有一个私有方法,在CREATE上调用。方法中的循环将生成随机散列,并对表执行READ以查看它是否唯一:如果是,则返回散列并将其注入CREATE请求。
我看到的问题是symfony中的我无法从实体类中访问存储库,因此我无法使用lifecycle callback。我理解这背后的原因。另一方面,哈希生成与控制器无关 - 对我而言,它是属于模型的内部逻辑。如果我以后更改数据结构,我需要编辑控制器。
我的问题是:架构方面,我应该在哪里放置哈希生成方法?
答案 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());
}
// ...
}
希望这有帮助