2011-12-13 17 views
4

在symfony2控制器中執行此操作會產生一個數組,其中每個單獨的結果本身就是一個對象..但我需要它也是一個數組,因此我可以輕鬆地json_encode整個列表Symfony2和Doctrine - 返回數據庫結果作爲控制器中的數組數組

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

那麼我如何得到一個數組的數組,而不是對象的數組,這就是我使用HYDRATE_ARRAY得到些什麼?

回答

4

我最終安裝了JMSSerializerBundle,它提供了我需要的方法。因爲我有一個鏈接的實體,我並不需要鏈接的對象,在我的實體類,我現在

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

通過添加@ExclusionPolicy(「無」)所有屬性都應該除標有排除被序列化。然後,在同一類的鏈接entitites剛纔添加的排除註釋

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

,並因此在控制器我現在可以做(添加使用的Symfony \分量\ HttpFoundation \響應之後;)

$serializer = $this->container->get('serializer'); 
$reports = $serializer->serialize($reports, 'json'); 
return new Response($reports); 

就是這樣。 Symfony + Doctrine可以使一些簡單的事情變得複雜。

2

沒有辦法,即開即用,告訴教義將對象視爲一個數組。但是,通過一些調整和一些可疑的設計決定,您可以實現這一目標。

您需要做的第一件事就是創建一個實現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的類。最後一塊難題是讓您的類屬性爲公開,以使json_encode函數能夠檢查您的類屬性並將它們用作json對象的鍵。

NB:在類中使用公有屬性會導致很多難以跟蹤的bug,並且通常被認爲是可疑的實踐。這只是一個例子,我很快就匆忙說明了如何實現。我相信有一種更優雅的方式來實現這一點,不需要公共屬性。該解決方案只是爲了讓球滾動

一個例子域類可能是這個樣子:

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"} 

編輯:只是爲了將您的代碼片段帶回到上下文中。你並不需要使用HYDRATE_ARRAY了,它只是看起來像這樣:

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

提供您的報告類擴展上述定義的domainObject的類。

+0

感謝您的幫助,但正如您所指出的,它不是暴露實體屬性的最佳解決方案,所以我採用了我在下面發佈的解決方案。 – Sofia