2008-11-10 24 views
14

मैं पीडीओ कथन से परिणामों के लिए एक इटरेटर लिखने की कोशिश कर रहा हूं लेकिन मुझे पहली पंक्ति में रीवाइंडिंग का कोई तरीका नहीं मिल रहा है। मैं fetchAll को कॉल करने और सभी परिणाम डेटा संग्रहीत करने के ऊपरी हिस्से से बचना चाहता हूं।क्या पीडीओ परिणाम रिवाइंड करना संभव है?

// first loop works fine 
foreach($statement as $result) { 
    // do something with result 
} 

// but subsequent loops don't 
foreach($statement as $result) { 
    // never called 
} 

क्या कथन को रीसेट करने या पहली पंक्ति की तलाश करने का कोई तरीका है?

उत्तर

10

मैं बहुत यकीन है कि यह डेटाबेस निर्भर है हूँ। इसके कारण, यह कुछ ऐसा है जो आपको टालने का प्रयास करना चाहिए। हालांकि, मुझे लगता है कि आप buffered queries सक्षम करके जो चाहते हैं उसे प्राप्त कर सकते हैं। यदि यह काम नहीं करता है, तो आप परिणाम को fetchAll के साथ हमेशा एक सरणी में खींच सकते हैं। दोनों समाधानों में आपके अनुप्रयोग प्रदर्शन के लिए प्रभाव पड़ते हैं, इसलिए परिणाम बड़े होने पर दो बार इसके बारे में सोचें।

1

आप शायद कुछ PHP एसपीएल कक्षाओं को देखना चाहते हैं जिन्हें ऑब्जेक्ट्स तक सरणी जैसी पहुंच प्रदान करने के लिए बढ़ाया जा सकता है।

+2

PdoStatement पहले से ही ट्रैवर्सबल लागू करता है – troelskn

8

slide 31 from this presentation देखें, यदि आप एक buffered क्वेरी पर लागू होते हैं तो आप $statement->rewind() कर सकते हैं। आप mysql का उपयोग करते हैं, तो आप PDO_MYSQL_ATTR_USE_BUFFERED_QUERY का उपयोग करके बफ़र प्रश्नों का अनुकरण कर सकते हैं:

$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1); 

@NoahGoodrich आप इशारा किया SPL करने के लिए। यहां एक उदाहरण दिया गया है जो हमेशा काम करता है:

$it = new ArrayIterator($stmt->fetchAll()); 
9

मैंने लिखा यह छोटा वर्ग मैंने पीडीओएसएटमेंट को लपेट लिया। यह केवल प्राप्त डेटा को संग्रहीत करता है। यदि यह काम नहीं करता है, तो आप फ़ाइल को पढ़ने और लिखने के लिए कैश को स्थानांतरित कर सकते हैं।

// Wrap a PDOStatement to iterate through all result rows. Uses a 
// local cache to allow rewinding. 
class PDOStatementIterator implements Iterator 
{ 
    public 
     $stmt, 
     $cache, 
     $next; 

    public function __construct($stmt) 
    { 
     $this->cache = array(); 
     $this->stmt = $stmt; 
    } 

    public function rewind() 
    { 
     reset($this->cache); 
     $this->next(); 
    } 

    public function valid() 
    { 
     return (FALSE !== $this->next); 
    } 

    public function current() 
    { 
     return $this->next[1]; 
    } 

    public function key() 
    { 
     return $this->next[0]; 
    } 

    public function next() 
    { 
     // Try to get the next element in our data cache. 
     $this->next = each($this->cache); 

     // Past the end of the data cache 
     if (FALSE === $this->next) 
     { 
      // Fetch the next row of data 
      $row = $this->stmt->fetch(PDO::FETCH_ASSOC); 

      // Fetch successful 
      if ($row) 
      { 
       // Add row to data cache 
       $this->cache[] = $row; 
      } 

      $this->next = each($this->cache); 
     } 
    } 
} 
0

बहुत समय पहले पूछे गए लेकिन वर्तमान में एक और समाधान है।

विधि PDOStatement::fetch()PDO::FETCH_ORI_* स्थिरांक में से एक के साथ दूसरा पैरामीटर, कर्सर ओरिएंटेशन प्राप्त कर सकता है। ये पैरामीटर केवल मान्य हैं यदि PDOStatementPDO::ATTR_CURSOR के साथ PDO::CURSOR_SCROLL के साथ एट्रिब्यूट के साथ बनाए गए हैं।

इस तरह आप निम्नानुसार नेविगेट कर सकते हैं। docs और PDO predefined constants में

$sql = "Select * From Tabela"; 
$statement = $db->prepare($sql, array(
    PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL, 
)); 
$statement->execute(); 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_NEXT); // return next 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_PRIOR); // return previous 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_FIRST); // return first 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_LAST); // return last 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_ABS, $n); // return to $n position 
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_REL, $n); // return to $n position relative to current 

अधिक जानकारी।

नोट: PDO::FETCH_BOTH का उपयोग किया गया डिफ़ॉल्ट है, बस इसे अपने प्रोजेक्ट के लिए अनुकूलित करें।

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