如何得到一个一维标量数组作为一个学说dql查询结果?
Posted
技术标签:
【中文标题】如何得到一个一维标量数组作为一个学说dql查询结果?【英文标题】:How to get a one-dimensional scalar array as a doctrine dql query result? 【发布时间】:2012-07-24 08:42:46 【问题描述】:我想从 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 做到这一点?
【问题讨论】:
【参考方案1】:由于 doctrine/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);
【讨论】:
【参考方案2】:php
您可以使用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
。
【讨论】:
getScalarResult() 会给你字符串 - 如果你想要整数,请使用 getArrayResult() 所以! array_column() 在内存管理方面更好还是 foreach 方式,我们应该怎么做?【参考方案3】:更好的解决方案是使用 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
【讨论】:
我已经修改了这个,所以它支持 indexBy gist.github.com/ostrolucky/f9f1e0b271357573fde55b7a2ba91a32【参考方案4】:从 PHP 5.5 开始,您可以使用array_column 来解决这个问题
$result = $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult();
$ids = array_column($result, "id");
【讨论】:
【参考方案5】:Ascarius 的回答很优雅,但要注意内存使用! array_map()
创建传递数组的副本并有效地使内存使用量翻倍。如果您使用数十万个数组项,这可能会成为一个问题。由于 PHP 5.4 调用时按引用传递已被删除,所以你不能这样做
// note the ampersand
$ids = array_map('current', &$result);
在这种情况下,你可以选择明显的
$ids = array();
foreach($result as $item)
$ids[] = $item['id'];
【讨论】:
这似乎有点违反直觉,因为我们的目标是在这两种情况下“几乎复制”数组。我必须亲自测试它才能确信它是真的:gist.github.com/PowerKiKi/9571aea8fa8d6160955f【参考方案6】:我认为这在 Doctrine 中是不可能的。 只需使用 PHP 将结果数组转换为您想要的数据结构:
$transform = function($item)
return $item['id'];
;
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
【讨论】:
以上是关于如何得到一个一维标量数组作为一个学说dql查询结果?的主要内容,如果未能解决你的问题,请参考以下文章