2013-10-16 1 views
1

고유 한 8 자의 영숫자 문자열이 포함되어야하는 고유 한 열이있는 DB 테이블이 있습니다.symfony 아키텍처 : 엔티티 생성시 리포지토리 액세스가있는 사용자 정의 메서드

나는 (마지막으로) 내 MVC 프레임 워크에서 symfony로 이동했습니다. 지금까지 CREATE에서 호출 된 모델에서 개인 메소드가 있었을 것입니다. 이 메서드의 루프는 무작위 해시를 생성하고 테이블에서 READ를 수행하여 고유한지 확인합니다. 그렇다면 해시가 반환되어 CREATE 요청에 삽입됩니다.

내가보기에 문제는 symfony에서 입니다. 엔티티 클래스 내에서 저장소에 액세스 할 수 없으므로 lifecycle callback을 사용할 수 없습니다. 나는 그 뒤에있는 추론을 이해한다. 반면 해시 생성은 컨트롤러와 아무 관련이 없습니다. 즉, 모델에 속한 내부 논리입니다. 나중에 데이터 구조를 변경하면 컨트롤러를 편집해야합니다.

제 질문은 아키텍처입니다. 해시 생성 방법은 어디에 두어야합니까?

엔터티 생성자에서

답변

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

createNewHash() 방법하는 것은 다음 컨트롤러로부터 호출 될 수있다, 그리고 상기 제어기는 해시 생성 자체를 염려 할 필요가 없다.

편집 : 청취자는이를 수행하는 또 다른 방법입니다.

0

이, 나는이를 추가 할 수 있습니다

내가 교리의 엔티티 관리자에 액세스 할 수있는 custom repository을 만들어 :

<?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

해시를 생성하는 방법을 알고 있습니다. 엔티티에서 DB가 실제로 고유한지 확인하기 위해 수행해야합니다. (생성 된 해시의 고유성에 대한이 설명을 참조하십시오. http://stackoverflow.com/a/4070171/698511) – Tim

+1

그래서 이벤트 리스너를 사용해야합니다. http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers .html – Picoss

+0

그들을 보았지만 EntityRepository로 관리했습니다 (내 답변 참조). 아마 여러 가지 방법이있을 수 있습니다. 도와 주셔서 감사합니다! – Tim

1

리스너를 사용할 수 있습니다. 라이프 사이클 콜백은 저장소에 대한 액세스가 필요하기 때문에 올바른 솔루션이 아니라는 것이 옳았습니다. 그러나 라이프 사이클 콜백과 동일한 이벤트를 수신하는 리스너를 정의 할 수 있지만 서비스이므로 종속성으로 저장소를 가질 수 있습니다.

관련 문제