2013-10-16 28 views
1

我有一個DB表,帶有一個UNIQUE列,該列應包含唯一的8個字符的字母數字字符串。我終於從我自己的MVC框架轉向symfony了。直到現在,我將在CREATE上調用的模型中擁有一個私有方法。該方法中的一個循環會生成一個隨機哈希,並在該表上執行一次READ以查看它是否是唯一的:如果是,則哈希將被返回並注入到CREATE請求中。symfony體系結構:創建實體時使用存儲庫訪問的自定義方法

,我看到它是symfony的我從實體類內到倉庫進不去了,所以我不能使用lifecycle callback的問題。我理解這背後的推理。另一方面,散列生成與控制器無關 - 對我來說屬於模型的是內部邏輯。如果稍後更改數據結構,我需要編輯控制器。

我的問題是:架構明智的,我應該在哪裏放置哈希生成方法?

回答

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)); 
    } 
} 

createNewHash()方法,然後可以從控制器調用,並且控制器沒有與哈希生成關心自己。

編輯:聽衆是這樣做的另一種方式。

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()); 
    } 

    // ... 

} 

希望這有助於

+0

謝謝,但我知道如何生成散列 - 我需要在實體中執行數據庫讀取以查看它是否真的是唯一的。 (請參閱生成哈希中唯一性的評論:http://stackoverflow.com/a/4070171/698511) – Tim

+1

所以你需要使用事件監聽器:http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers .html – Picoss

+0

看着他們,但設法與一個EntityRepository(見我的答案)。有可能有幾種方法來做到這一點。謝謝您的幫助! – Tim

1

您可以使用偵聽器。你說得對,生命週期回調不是正確的解決方案,因爲你需要訪問版本庫。但是你可以定義一個偵聽器來偵聽與生命週期回調相同的事件,但是它是一種服務,因此可以將存儲庫作爲依賴項。