Frage

Ich versuche, einen Iterator für die Ergebnisse einer PDO-Anweisung zu schreiben, aber ich kann nicht jede mögliche Weise von Zurückspulen in der ersten Reihe finden. Ich möchte den Aufwand der Aufruf fetchAll vermeiden und alle Ergebnisdaten zu speichern.

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

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

Gibt es eine Möglichkeit, die Mitteilung des Reseting oder die erste Zeile suchen?

War es hilfreich?

Lösung

Ich bin mir ziemlich sicher, dass dies die Datenbank abhängig ist. Aus diesem Grund ist es etwas, das Sie versuchen sollten, zu vermeiden. Aber ich denke, können Sie erreichen, was Sie wollen von gepuffert Abfragen ermöglicht. Wenn das nicht funktioniert, können Sie immer das Ergebnis in einem Array ziehen mit fetchAll . Beide Lösungen haben Auswirkungen auf Ihre Anwendungen Leistung, so denken Sie zweimal darüber nach, wenn die Result groß sind.

Andere Tipps

Diese kleine Klasse schrieb ich wickelt eine PDOStatement. Es speichert nur die Daten, die abgerufen werden. Wenn dies nicht funktioniert, können Sie den Cache bewegen, um eine Datei zu lesen und zu schreiben.

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

finden Sie unter 31 gleiten aus dieser Präsentation , können Sie eine $statement->rewind() tun wenn es gilt für eine gepufferte Abfrage. Wenn Sie MySQL verwenden, können Sie gepufferte Abfragen emulieren, indem PDO_MYSQL_ATTR_USE_BUFFERED_QUERY mit:

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

@NoahGoodrich wies Sie spl. Hier ist ein Beispiel, das immer funktioniert:

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

Sie werden wahrscheinlich wollen einen Blick auf einige der PHP SPL Klassen nehmen, die erweitert werden kann Array-ähnlichen Zugriff auf Objekte zu schaffen.

vor langer Zeit gefragt, aber derzeit gibt es eine andere Lösung.

Die Methode PDOStatement::fetch() kann einen zweiten Parameter, um die Cursor Ausrichtung, mit einem von PDO::FETCH_ORI_* Konstanten erhält. Diese Parameter sind nur gültig, wenn der PDOStatement mit dem atribute PDO::ATTR_CURSOR als PDO::CURSOR_SCROLL erstellt werden.

So können Sie wie folgt navigieren können.

$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

Weitere Informationen unter docs und < a href = "http://php.net/manual/en/pdo.constants.php" rel = "nofollow"> PDO vordefinierte Konstanten .

Hinweis: verwendet PDO::FETCH_BOTH weil der Standard ist, passen Sie es nur für Ihr Projekt

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top