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

Php 如何获得一维标量数组作为dql查询结果?,php,doctrine-orm,Php,Doctrine Orm,我想从拍卖表的id列中获取一个值数组。 如果这是一个原始SQL,我会写: SELECT id FROM auction 但当我在教义中这样做并执行: $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); 我得到的数组如下所示: array( array('id' => 1), array('id' => 2), ) array( 1, 2 ) $em-

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

SELECT id FROM auction
但当我在教义中这样做并执行:

$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); 
我得到的数组如下所示:

array(
    array('id' => 1),
    array('id' => 2),
)
array(
    1,
    2
)
$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");
相反,我希望得到如下数组:

array(
    array('id' => 1),
    array('id' => 2),
)
array(
    1,
    2
)
$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");

我怎样才能用条令做到这一点呢?

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

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
PHP<5.5 您可以使用
array\u map
,因为每个数组只有on项,所以您可以优雅地使用
'current'
作为回调,而不是编写回调函数

有关内存使用情况的更多信息,请参阅

PHP>=5.5
同样,建议使用
array\u column

Ascarius的答案很优雅,但要注意内存使用
array\u map()
创建所传递数组的副本,有效地将内存使用率提高一倍。如果使用数十万个数组项,这可能会成为一个问题。由于PHP5.4调用时间传递引用已被删除,因此无法执行此操作

// note the ampersand
$ids = array_map('current', &$result);
在这种情况下,你可以选择显而易见的

$ids = array();
foreach($result as $item) {
  $ids[] = $item['id'];
}
从PHP5.5开始,您可以使用

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

更好的解决方案是使用
PDO:FETCH\u 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');
您可以这样使用它:

array(
    array('id' => 1),
    array('id' => 2),
)
array(
    1,
    2
)
$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");
更多信息:

这似乎有点违反直觉,因为我们的目标是在这两种情况下“几乎复制”阵列。我必须亲自测试它才能确信它是真的:getScalarResult()将为您提供字符串-如果您想要整数,请使用getArrayResult()!array_column()在内存管理方面更好吗?还是它是foreach方法,我们应该怎么做?我已经修改了它,以便它支持indexBy