如何将一维标量数组作为doctrine dql查询结果?

时间:2012-07-25 20:10:51

标签: php doctrine-orm

我想从Auction表的id列中获取一组值。 如果这是一个原始SQL我会写:

SELECT id FROM auction

但是当我在Doctrine中执行此操作并执行时:

$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); 

我得到一个这样的数组:

array(
    array('id' => 1),
    array('id' => 2),
)

相反,我想得到一个这样的数组:

array(
    1,
    2
)

我如何使用Doctrine来做到这一点?

5 个答案:

答案 0 :(得分:182)

PHP< 5.5

您可以使用array_map,因为您只有每个数组的项目,所以您可以优雅地使用 'current'作为回调,而不是撰写closure

$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_map('current', $result);
  

有关内存使用情况的其他信息,请参阅Petr Sobotka's answer below

PHP> = 5.5

作为jcbwlkr's answered below,建议使用array_column

答案 1 :(得分:126)

从PHP 5.5起,您可以使用array_column来解决此问题

$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_column($result, "id");

答案 2 :(得分:82)

更好的解决方案是使用PDO:FETCH_COLUMN。要做到这一点,你需要一个定制的保湿剂:

//MyProject/Hydrators/ColumnHydrator.php
namespace DoctrineExtensions\Hydrators\Mysql;

use Doctrine\ORM\Internal\Hydration\AbstractHydrator, PDO;

class ColumnHydrator extends AbstractHydrator
{
    protected function hydrateAllData()
    {
        return $this->_stmt->fetchAll(PDO::FETCH_COLUMN);
    }
}

将其添加到Doctrine:

$em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');

你可以像这样使用它:

$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");

更多信息: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes

答案 3 :(得分:17)

Ascarius'答案很优雅,但要注意内存使用情况! array_map()创建传递数组的副本,并有效地使内存使用量翻倍。如果您使用数十万个数组项,这可能会成为一个问题。由于PHP 5.4通过引用传递的调用时间已被删除,因此您无法执行

// note the ampersand
$ids = array_map('current', &$result);

在这种情况下,您可以使用明显的

$ids = array();
foreach($result as $item) {
  $ids[] = $item['id'];
}

答案 4 :(得分:4)

我认为在学说中这是不可能的。 只需使用PHP将结果数组转换为您想要的数据结构:

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());