doctrine dqlクエリ結果として1次元スカラー配列を取得するにはどうすればよいですか?


116

オークションテーブルの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を使用してどうすればよいですか?

回答:


197

PHP <5.5

を使用できますarray_map。また、配列ごとの項目しか持たないため'current'クロージャーを作成する代わりに、エレガントにコールバックとして使用でき ます。

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

参照してください以下ペトルSobotkaの答えメモリの使用状況に関する追加情報のために。

PHP> = 5.5

jcbwlkrの下に答え、それが使用することをお勧めの方法array_column


9
getScalarResult()は文字列を提供します-整数が必要な場合はgetArrayResult()を使用してください
pHoutved

そう!array_column()はメモリ管理に優れていますか、それともforeach方法ですか?
Dheeraj 2017年

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);
    }
}

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



18

Ascariusの答えはエレガントですが、メモリ使用量に注意してください!array_map()渡された配列のコピーを作成し、実質的にメモリ使用量を2倍にします。何十万ものアレイアイテムを扱う場合、これは問題になる可能性があります。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

4

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

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.