Doktrin dql sorgu sonucu olarak tek boyutlu bir skaler dizi nasıl elde edilir?


116

Açık Artırma tablosunun id sütunundan bir dizi değer almak istiyorum. Bu ham bir SQL olsaydı şunu yazardım:

SELECT id FROM auction

Ama bunu Doctrine'de yaptığımda ve uyguladığımda:

$em->createQuery("SELECT a.id FROM Auction a")->getScalarResult(); 

Bunun gibi bir dizi alıyorum:

array(
    array('id' => 1),
    array('id' => 2),
)

Bunun yerine, bunun gibi bir dizi elde etmek istiyorum:

array(
    1,
    2
)

Bunu Doctrine kullanarak nasıl yapabilirim?

Yanıtlar:


197

PHP <5.5

Kullanabilirsiniz array_mapve her dizi için yalnızca öğeye sahip olduğunuzdan, 'current'bir kapanış yazmak yerine zarif bir şekilde geri arama olarak kullanabilirsiniz .

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

Bkz aşağıda Petr Sobotka yanıtını bellek kullanımı ile ilgili ek bilgi için.

PHP> = 5.5

As jcbwlkr en aşağıda cevap , tavsiye edilen yolu kullanmak array_column.


9
getScalarResult () size dizeler verecektir - tam sayı istiyorsanız getArrayResult () kullanın
pHoutved

yani! array_column () bellek yönetiminde daha mı iyi yoksa foreach yolu mu, ne yapmalıyız?
Dheeraj

151

PHP 5.5'ten itibaren bunu çözmek için array_column kullanabilirsiniz

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

98

Daha iyi bir çözüm kullanmaktır PDO:FETCH_COLUMN. Bunu yapmak için özel bir hidratöre ihtiyacınız var:

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

Doktrine Ekle:

$em->getConfiguration()->addCustomHydrationMode('COLUMN_HYDRATOR', 'MyProject\Hydrators\ColumnHydrator');

Ve bunu şu şekilde kullanabilirsiniz:

$em->createQuery("SELECT a.id FROM Auction a")->getResult("COLUMN_HYDRATOR");

Daha fazla bilgi: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#custom-hydration-modes



18

Ascarius'un cevabı zarif, ancak hafıza kullanımına dikkat edin! array_map()geçirilen dizinin bir kopyasını oluşturur ve bellek kullanımını etkin bir şekilde iki katına çıkarır. Yüzbinlerce dizi öğesiyle çalışırsanız, bu bir sorun haline gelebilir. Referansla PHP 5.4 çağrı zamanı geçişi kaldırıldığından, bunu yapamazsınız

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

Bu durumda bariz bir şekilde gidebilirsiniz

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

2
Hedefimiz diziyi her iki durumda da "neredeyse kopyalamak" olduğundan, bu biraz mantıksız göründü. Bunun gerçekten doğru olduğuna ikna olmak için kendim test etmem gerekiyordu: gist.github.com/PowerKiKi/9571aea8fa8d6160955f
PowerKiKi

4

Doctrine'de imkansız olduğunu düşünüyorum. Sonuç dizisini PHP kullanarak istediğiniz veri yapısına dönüştürün:

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.