एक डॉक्ट्रिन डकल क्वेरी परिणाम के रूप में एक आयामी स्केलर सरणी कैसे प्राप्त करें?


116

मैं नीलामी तालिका के आईडी कॉलम से मूल्यों की एक सरणी प्राप्त करना चाहता हूं। अगर यह एक कच्ची एसक्यूएल होती तो मैं लिखता:

SELECT id FROM auction

लेकिन जब मैं Doctrine में ऐसा करता हूं और निष्पादित करता हूं:

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

मुझे इस तरह एक सरणी मिलती है:

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

इसके बजाय, मैं इस तरह एक सरणी प्राप्त करना चाहते हैं:

array(
    1,
    2
)

मैं उस सिद्धांत का उपयोग कैसे कर सकता हूं?

जवाबों:


197

PHP <5.5

आप उपयोग कर सकते हैं array_map, और चूँकि आपके पास प्रति आइटम पर केवल सरणी है, आप 'current'एक बंद लिखने के बजाय, कॉलबैक के रूप में सुरुचिपूर्ण ढंग से उपयोग कर सकते हैं ।

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

मेमोरी उपयोग के बारे में अतिरिक्त जानकारी के लिए पेट्र सोबोटका का जवाब नीचे देखें ।

PHP> = 5.5

जैसा कि नीचे दिया गया है jcbwlkr , ने इसे इस्तेमाल करने का अनुशंसित तरीका बताया array_column


9
getScalarResult () आपको स्ट्रिंग्स देगा - getArrayResult () का उपयोग करें यदि आप पूर्णांक चाहते हैं
pHoutved

इसलिए! स्मृति प्रबंधन में array_column () बेहतर है या क्या यह फ़ॉरच तरीका है, हम क्या करते हैं?
धीरज

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

इसे सिद्धांत में जोड़ें:

$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


2
मैंने इसे संशोधित किया है, इसलिए यह indexBy gist.github.com/ostrolucky/f9f1e0b271357573fde55b7a2ba91a32
15

18

Ascarius का जवाब सुरुचिपूर्ण है, लेकिन स्मृति उपयोग से सावधान रहें! array_map()पारित सरणी की एक प्रति बनाता है और स्मृति उपयोग को प्रभावी ढंग से दोगुना करता है। यदि आप सैकड़ों हज़ारों सरणी वस्तुओं के साथ काम करते हैं तो यह एक मुद्दा बन सकता है। चूंकि PHP 5.4 कॉल-टाइम पास संदर्भ द्वारा हटा दिया गया है इसलिए आप ऐसा नहीं कर सकते

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

उस मामले में आप स्पष्ट रूप से जा सकते हैं

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

2
यह थोड़ा सा सहज ज्ञान युक्त लग रहा था, क्योंकि हमारा लक्ष्य दोनों मामलों में सरणी को "लगभग कॉपी" करना है। मुझे खुद यह परखना था
PowerKiKi

4

मुझे लगता है कि यह डॉक्ट्रिन में असंभव है। परिणाम संरचना को केवल उस डेटा संरचना में बदलें जिसे आप PHP का उपयोग करना चाहते हैं:

$transform = function($item) {
    return $item['id'];
};
$result = array_map($transform, $em->createQuery("SELECT a.id FROM Auction a")->getScalarResult());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.