2009-09-07 13 views
19

मैं डेटाबेस से पूछताछ के लिए PDOStatement का उपयोग कर रहा हूं। जब भी मुझे एक लौटाई पंक्ति मिलती है, तो मैं चाहता हूं कि इसे $row[0] कुंजी के रूप में, और पंक्ति के बाद के तत्वों के रूप में पंक्ति के रूप में एक सरणी में लाया जाए।PHP पीडीओएसएटेमेंट: एक पंक्ति प्राप्त करें, पहले कॉलम के रूप में पहले एरे की कुंजी

मैं, ज़ाहिर है, foreach छोरों और if सशर्त, का एक संयोजन लिख सकते हैं इस तरह के नीचे के रूप में काम करने के लिए,:

private static function GetMySQLResult($dbname, $sqlString) { 


     $dbh = self::ConstructPDOObject($dbname); 
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

     $result=array(); 
     foreach ($dbh->query($sqlString) as $row) 
     { 
      $result[$row[0]][]=$row[1]; // the simplest case for 2 columns, should add more to handle more columns 

     } 

     return $result; 

} 

लेकिन मैं एक मौजूदा विधि रहा हूँ; क्या ऐसी कोई विधि पहले से ही मौजूद है?

+0

आपका कोड वास्तव में एक गैर-अद्वितीय कुंजी पर पंक्तियों को समूहित करता है, क्या यह एक संभावित उत्तर की आवश्यकता भी है? –

उत्तर

2

कुछ टिप्स, आपको PDOStatement->fetch() विधि पर सही फ़ेच शैली को पारित करने की आवश्यकता है ताकि आप डबल डेटा (संख्यात्मक और टेक्स्ट कॉलम नाम) के साथ समाप्त न हों। जब आप पीडीओ :: FETCH_BOTH का उपयोग करते हैं तो $ पंक्ति [0] और $ पंक्ति ['id'] की तरह दोनों में समान मूल्य होता है।

$result = $dbh->query($sqlString); 
while ($row = $result->fetch(PDO::FETCH_NUM)) { 
... 

अपने प्रश्न के लिए के रूप में, आप सभी परिणाम लाने और फिर $ पंक्ति [ 'आईडी'] कुंजी और मान के रूप में परिणाम पंक्ति के रूप में के साथ एक सरणी बनाने के लिए होगा - आप जैसे कर रहे हैं । मैंने पीडीओ के आसपास एक संपूर्ण ओआरएम लाइब्रेरी बनाई और मुझे इसे स्वचालित रूप से करने के लिए कुछ भी नहीं मिला।

$result = $dbh->query($sqlString); 

$results = array(); 
while ($row = $result->fetch(PDO::FETCH_NUM)) { 
    $results[$row[0]] = $row; 
} 

return $results; 
+0

फ़ोरैच लूप का उपयोग करने के लिए यह अलग कैसे है, जो हम बचने की कोशिश कर रहे हैं? –

22

क्रेडिट devdRew पर जाएं। Check the other question here

स्पष्ट रूप से, आप उत्तर में बताए गए अनुसार कर सकते हैं। मैंने भी जांच की और यह बहुत अच्छा काम करता है। 1 कुंजी और 1 मूल्य:

$q = $db->query("SELECT `name` AS name, `value` AS value FROM `settings`;"); 
$r = $q->fetchAll(PDO::FETCH_KEY_PAIR); 

संपादित

यह जवाब है कि आप अधिक से अधिक 2 कॉलम निर्दिष्ट की आवश्यकता है। यदि आपको डेटाबेस से अधिक कुंजी पुनर्प्राप्त करने की आवश्यकता है, तो नीचे दिए गए उत्तर की जांच करें और @nullabilty की टिप्पणी पढ़ें। जो लोग आलसी हैं के लिए, यहाँ उसकी विधि है:

$q->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC); 
+0

यह एकमात्र तरीका है जो पहले कॉलम को कुंजी के रूप में उपयोग करेगा, क्या आपको अतिरिक्त कॉलम, CONCAT या अन्य कॉलम मान के लिए सीमित स्ट्रिंग के रूप में अतिरिक्त फ़ील्ड की आवश्यकता होनी चाहिए और मान का उपयोग करने से पहले सरणी रखने के लिए 'विस्फोट' का उपयोग करना चाहिए। –

+0

@ निकल- इस उद्देश्य के लिए 'कंकैट' का उपयोग करना एक भयानक विचार है; यह उत्तर विशेष रूप से कुंजी-मूल्य जोड़े के लिए उपयोग किया जाना चाहिए, जिसके लिए इसे डिज़ाइन किया गया था। –

+0

क्या आप बक्षीस की अवधि समाप्त कर रहे हैं? –

1

दो स्तंभ तालिका परिदृश्य के अलावा, वहाँ पीडीओ स्तर इस संभाल करने में कुछ भी नहीं है, लेकिन आप इसके लिए एक पुन: प्रयोज्य इटरेटर लिख सकता है, इस तरह:

class FirstColumnKeyIterator implements Iterator 
{ 
    private $stmt; 
    private $key; 
    private $data; 
    private $mode; 

    public function __construct(PDOStatement $stmt, $fetch_mode = PDO::FETCH_NUM) 
    { 
     $this->stmt = $stmt; 
     $this->mode = $fetch_mode; 
     $this->fetch(); 
    } 

    private function fetch() 
    { 
     if (false !== ($this->data = $this->stmt->fetch($this->mode))) { 
      $this->key = current(array_splice($this->data, 0, 1)); 
     } 
    } 

    public function rewind() 
    { 
     // nil operation 
    } 

    public function key() 
    { 
     return $this->key; 
    } 

    public function current() 
    { 
     return $this->data; 
    } 

    public function next() 
    { 
     $this->fetch(); 
    } 

    public function valid() 
    { 
     return false !== $this->data; 
    } 
} 

निर्माता एक PDOStatement लेता है और एक वैकल्पिक मोड लाने (डिफ़ॉल्ट रूप से सांख्यिक स्तंभ है, लेकिन एक साहचर्य सरणी के लिए PDO::FETCH_ASSOC को बदला जा सकता है) और आप एक विशिष्ट foreach का उपयोग कर क्वेरी परिणामों से अधिक पुनरावृति करने देता है।

प्रयोग उदाहरण:

$dbh = new PDO(/* etc */); 

$stmt = $dbh->query('SELECT * FROM accounts'); 
foreach (new FirstColumnKeyIterator($stmt, PDO::FETCH_ASSOC) as $key => $value) { 
     echo $key, ' = ', print_r($value, true), PHP_EOL; 
} 
+0

रचनात्मकता के लिए 10 अंक =) लेकिन आप इस तरह से अधिक महंगा पाएंगे मूल परिदृश्य आप पहले 'नए इटरेटर' को संदर्भित करके इसे बेहतर बना सकते हैं और यदि आप इसकी सहायता कर सकते हैं तो हमेशा '$ key => # value' से बचें। आप पाएंगे कि एक संदर्भित 'array_keys' पर लूप के लिए तब तक बेहतर परिणाम मिलेगा जब तक कि गणना भी संदर्भित की जाती है। 'के लिए ($ i = 0; $ i <गिनती ($ डेटा); $ i ++) 'सबसे खराब लूप को सबसे मजबूत लूप में बदल देता है और मुझे अपना पैसा वापस लेना चाहिए। –

+0

@ निकल इटरेटर्स हमेशा "सादा" सरणी से अधिक महंगे होते हैं क्योंकि प्रत्येक लूप पर अतिरिक्त कोड निष्पादित होता है जो उदाहरण के संदर्भ में दूर नहीं जायेगा; 'key => value' को हटाने का विकल्प एक विकल्प नहीं है, क्योंकि अन्यथा कुंजी प्राप्त करने का कोई तरीका नहीं है :) –

+0

एक पुनरावर्तक का उपयोग करने के वैकल्पिक तरीके और अभी भी कुंजी प्राप्त करने के साथ ... या उस मामले के दौरान हो सकता है और मैं लूप के लिए कई के बारे में सोच सकता हूं यानी। 'के लिए ($ it = new ArrayIterator ($ डेटा); $ it-> मान्य(); $ it-> अगला()) echo $ it-> कुंजी()। ' => '। $ it-> वर्तमान(); 'लेकिन मुझे यकीन है कि आपने इनके बारे में भी सोचा था।=) –

3

AFAIK, वहाँ कोई मौजूदा विधि करना होगा कि कि PHP में लेकिन वहाँ तरीकों से आप प्राप्त कर सकते थे कि आप क्या चाहते की एक जोड़ी रहे हैं।

पहले से एक होने के क्या Xeoncross कहा लेकिन थोड़ा संशोधित:

$pdostmt = $pdo->query("SELECT ... FROM your_table"); 

$res = array(); 

foreach ($pdostmt->fetchAll(PDO::FETCH_ASSOC) as $row) 
{ 
    $res[array_shift($row)] = $row; 
} 

अन्यथा, आप एक __set() विधि के साथ एक वर्ग बना सकते हैं चर काम को पकड़ने के लिए:

class at_res 
{ 
    public $key; 
    public $values = array(); 
    protected $flag = true; 

    public function __set($var, $value) 
    { 
    if ($this->flag) 
    { 
     $this->key = $value; 
     $this->flag = false; 
    } 
    else 
    { 
     $this->values[$var] = $value; 
    } 
    } 

    public function extract() 
    { 
    return array($this->key => $this->values); 
    } 
} 


$pdo = new PDO(...); 

$pdostmt = $pdo->query("SELECT ... FROM your_table"); 

$res = $pdostmt->fetchObject('at_res'); 

var_dump($res->extract()); 

आशा है कि यह मदद करता है ।

13
$stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE); 

हैक का एक सा है, लेकिन वास्तव के बाद से किसी decided FETCH_KEY_PAIR यह करने के लिए एक ही रास्ता यद्यपि 2 स्तंभ परिणाम सेट का एकमात्र किया जा सकेगा।

नोट: पहला कॉलम एक कुंजी का उपयोग किया जाता है और किसी भी अन्य रूप में परिणाम सेट में वापस नहीं किया जाता है।

+13

धन्यवाद, मैंने अपनी पीडीओ :: FETCH_GROUP | पीडीओ :: FETCH_UNIQUE तक बढ़ाया। पीडीओ :: FETCH_ASSOC' जो मुझे चाहिए उसे ठीक करने के लिए। – nullability

+0

अच्छा जोड़ा वहाँ thx – Louis

+0

नोट: पहला कॉलम एक कुंजी का उपयोग किया जाता है और किसी भी अन्य रूप में परिणाम सेट में वापस नहीं किया जाता है। यदि आप कॉलम प्राप्त करना चाहते हैं तो आप अभी भी "पहले चयन करें AS आईडी, firstcolumn, secondcolumn ..." का उपयोग करके अपना पहला कॉलम डुप्लिकेट कर सकते हैं। –

संबंधित मुद्दे