2011-12-13 5 views
4

symfony2 컨트롤러에서이 작업을 수행하면 각 단일 결과 자체가 객체입니다. 결과적으로 배열이기도하지만 쉽게 배열 할 수 있습니다. 내가 HYDRATE_ARRAY를 사용하여 얻고 무엇을하는 배열의 배열이 아닌 객체의 배열을 얻는 방법 그래서 전체 목록Symfony2와 Doctrine - 컨트롤러의 배열 배열로 데이터베이스 결과를 반환합니다.

$em->getRepository('MyBundle:Report')->findByEvaluation($evaluation_id, \Doctrine\ORM\Query::HYDRATE_ARRAY) 

을로 json_encode?

답변

4

필자는 필요한 방법을 제공하는 JMSSerializerBundle을 설치했습니다. 내가 링크 된 개체를했고 내가 연결된 개체를 필요로하지 않았기 때문에, 내 엔티티 클래스에 내가 지금 모든 속성이 제외로 표시된 제외 직렬화해야 @ExclusionPolicy ("없음")를 추가하여

... 
use JMS\SerializerBundle\Annotation\ExclusionPolicy; 
use JMS\SerializerBundle\Annotation\Exclude; 
/** 
* Iddp\RorBundle\Entity\Report 
* 
* @ORM\Table() 
* @ORM\Entity(repositoryClass="Iddp\RorBundle\Entity\ReportRepository") 
* @ExclusionPolicy("None") 
*/ 
class Report 

있습니다.

$serializer = $this->container->get('serializer'); 
$reports = $serializer->serialize($reports, 'json'); 
return new Response($reports); 
(사용 심포니 \ 구성 요소 \ HttpFoundation 응답 \ 추가 한 후) 다음에, 같은 클래스에서 링크 된 entitites에 바로이 주석에게

/** 
* @ORM\ManyToOne(targetEntity="Client", inversedBy="reports") 
* @ORM\JoinColumn(name="client_id", referencedColumnName="id") 
* @Exclude 
*/ 
protected $client; 

그래서 컨트롤러 내가 지금 할 수있는 제외 추가

그게 전부입니다. Symfony + Doctrine은 복잡한 것을 복잡하게 만들 수 있습니다.

2

Doctrine에게 객체를 배열로 취급하도록 알려주는 방법은 없습니다. 그러나 약간의 조정과 의심스러운 디자인 결정을 통해이를 달성 할 수 있습니다.

먼저해야 할 일은 ArrayAccess 인터페이스를 구현하는 기본 클래스 (확장 할 클래스 용)를 만드는 것입니다. 이에 대해 설명하는 문서는 Doctrine cookbook에서 찾을 수 있습니다. 그것은 다음과 같이 보일 것입니다 :

abstract class DomainObject implements ArrayAccess 
{ 

    public function offsetExists($offset) 
    { 
     return isset($this->$offset); 
    } 

    public function offsetSet($offset, $value) 
    { 
     throw new BadMethodCallException(
      "Array access of class " . get_class($this) . " is read-only!" 
     ); 
    } 

    public function offsetGet($offset) 
    { 
     return $this->$offset; 
    } 

    public function offsetUnset($offset) 
    { 
     throw new BadMethodCallException(
      "Array access of class " . get_class($this) . " is read-only!" 
     ); 
    } 

} 

그런 다음 모델 클래스를 생성 (또는 적어도 당신이 배열로 처리 할 것들)이 DomainObject 클래스를 확장해야 할 때. 퍼즐의 마지막 부분은 클래스 속성을 public으로 만들어 클래스 속성을 검사하고 json 객체의 키로 사용할 수있는 기능을 json_encode 함수에 제공하는 것입니다.

NB : 클래스의 공개 속성을 사용하면 버그를 추적하기가 어려울 수 있으며 일반적으로 문제의 관행으로 간주됩니다. 이것은 내가 그것을 어떻게 달성 할 수 있었는지를 설명하기 위해 빨리 채찍질 한 예일뿐입니다. 공개 속성이 필요하지 않은 이것을 구현하는보다 우아한 방법이있을 것이라고 확신합니다. 이 솔루션은 단지 다음과 같이 보일 수

예 도메인 클래스를 압연 공을하기위한 것입니다 :

이제
class Tester extends DomainObject 
{ 

    public $foo; 

    public $bar; 

    public function __construct($foo, $bar) 
    { 

     $this->foo = $foo; 
     $this->bar = $bar; 

    } 

} 

당신이 배열과 패스 테스터 클래스의 인스턴스를 캐스팅 할 수 있습니다 이 배열로 json_encode한다 :

$test = new Tester('Hello', 'World'); 
echo json_encode((array)$test); 

다음 출력을 생성 할 것이다 어느 :

{"foo":"Hello","bar":"World"} 

EDIT : 코드 스 니펫을 다시 컨텍스트로 가져 오는 것입니다. 당신은 그냥 다음과 같을 것이다, 더 이상 HYDRATE_ARRAY를 사용할 필요가 없습니다 :

$results = $em->getRepository('MyBundle:Report')->findByEvaluation($evaluation_id); 
foreach ($results as $result) { 
    echo json_encode((array)$result); 
} 

은 보고서 클래스는 위에서 정의 된 DomainObject 클래스를 확장 제공.

+0

도움 주셔서 감사하지만 내가 지적한대로 엔티티의 속성을 노출시키는 최선의 해결책이 아니므로 아래에 게시 된 솔루션과 함께갔습니다. – Sofia

관련 문제