Symfony2和Doctrine - 将数据库结果作为控制器中的数组数组返回

时间:2011-12-13 04:27:46

标签: symfony doctrine doctrine-orm

在symfony2控制器中执行此操作会产生一个数组,其中每个结果本身就是一个对象..但我需要它也是一个数组,所以我可以很容易地json_encode整个列表

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

那么我如何获得一个数组数组而不是一个对象数组,这是我使用HYDRATE_ARRAY得到的?

2 个答案:

答案 0 :(得分: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(“None”),除了标记为exclude的属性外,所有属性都应序列化。然后,在同一类中的链接权限中,只需添加排除注释

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

所以在控制器中我现在可以做了(添加后使用Symfony \ Component \ HttpFoundation \ Response;)

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

就是这样。 Symfony + Doctrine可以使一些简单的事情变得复杂。

答案 1 :(得分: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_encode函数能够检查您的类属性并将它们用作json对象的键。

NB :在类中使用公共属性会导致很多难以追踪的错误,并且通常被认为是有问题的做法。这只是我迅速掀起的一个例子来说明如何实现它。我确信有一种更优雅的方式来实现它,不需要公共属性。这个解决方案只是为了让球滚动

示例域类可能如下所示:

class Tester extends DomainObject
{

    public $foo;

    public $bar;

    public function __construct($foo, $bar)
    {

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

    }

}

现在,您将能够将Tester类的实例强制转换为数组并将该数组传递给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);
}

如果您的Report类扩展了上面定义的DomainObject类。