如何获得一维标量数组作为dql学说的查询结果?


116

我想从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
)

我该如何使用教义做到这一点?

Answers:


197

PHP <5.5

您可以使用array_map,并且由于每个数组仅包含一个项目,因此可以优雅地 'current'用作回调,而不必编写闭包

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

有关内存使用的其他信息,请参见下面的Petr Sobotka的答案

PHP> = 5.5

正如下面jcbwlkr的回答,推荐使用它的方式array_column


9
getScalarResult()将为您提供字符串-如果需要整数,请使用getArrayResult()
pHoutved

所以!array_column()在内存管理方面是更好的方法还是foreach方法,我们应该做什么?
Dheeraj

151

从PHP 5.5开始,您可以使用array_column解决此问题

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

98

更好的解决方案是使用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);
    }
}

将其添加到主义:

$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


2
我已对此进行了修改,使其支持indexBy gist.github.com/ostrolucky/f9f1e0b271357573fde55b7a2ba91a32
gadelat

18

Ascarius的回答很优雅,但请注意内存使用!array_map()创建一个传递数组的副本,并有效地使内存使用量增加一倍。如果您使用成千上万个数组项,则可能会成为问题。由于PHP 5.4调用时按引用传递已被删除,因此您无法执行

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

在这种情况下,您可以选择

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

2
这似乎有点违反直觉,因为我们的目标是在两种情况下“几乎复制”阵列。我必须自己进行测试才能确信它确实是真的:gist.github.com/PowerKiKi/9571aea8fa8d6160955f
PowerKiKi 2014年

4

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

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.