133

我想从 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 做到这一点?

4

6 回答 6

209

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

于 2012-12-20T09:45:44.247 回答
175

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

$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_column($result, "id");
于 2014-09-26T14:16:40.353 回答
103

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

于 2015-07-09T12:03:49.887 回答
18

Ascarius 的回答很优雅,但要注意内存使用!array_map()创建传递数组的副本并有效地使内存使用量翻倍。如果您使用数十万个数组项,这可能会成为一个问题。由于 PHP 5.4 调用时按引用传递已被删除,所以你不能这样做

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

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

$ids = array();
foreach($result as $item) {
  $ids[] = $item['id'];
}
于 2014-03-15T12:49:33.653 回答
5

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

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
于 2012-07-27T09:29:06.667 回答
5

由于教义/orm 2.10.0有一个内置的解决方案,请参阅https://www.doctrine-project.org/projects/doctrine-orm/en/2.10/reference/dql-doctrine-query-language。 html#scalar-column-hydration

use Doctrine\ORM\AbstractQuery;

$query = $em->createQuery("SELECT a.id FROM Auction a");
return $query->getSingleColumnResult();
// Same as:
return $query->getResult(AbstractQuery::HYDRATE_SCALAR_COLUMN);
于 2021-11-06T13:15:43.033 回答