web-dev-qa-db-ja.com

1次元スカラー配列をdoctrine dqlクエリ結果として取得する方法は?

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を使用してそれを行うにはどうすればよいですか?

100
Dawid Ohia

PHP <5.5

array_mapを使用できます。また、配列ごとにアイテムがあるだけなので、 closure を記述する代わりに、'current'をコールバックとしてエレガントに使用できます。

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

メモリ使用量に関する追加情報については、 Petr Sobotkaの以下の回答 を参照してください。

PHP> = 5.5

jcbwlkrの回答 のように、array_columnを使用する推奨方法。

184
Lionel Gaillard

PHP 5.5以降、 array_column を使用してこれを解決できます

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

より良い解決策は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

89
Ioan Badila

Ascariusの答えはエレガントですが、メモリ使用量に注意してください! array_map()は、渡された配列のコピーを作成し、メモリ使用量を効果的に2倍にします。数十万の配列アイテムを扱う場合、これが問題になる可能性があります。 PHP 5.4参照による呼び出し時パスが削除されたため、実行できません

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

その場合、あなたは明白に行くことができます

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

Doctrineでは不可能だと思います。 PHPを使用して、結果の配列を必要なデータ構造に変換するだけです。

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