W3docs

PHP mysqli_use_result() — Ungepufferte Ergebnismengen erklärt

Erfahren Sie, wie mysqli_use_result() eine ungepufferte MySQL-Ergebnismenge initiiert, Unterschiede zu mysqli_store_result() und wann man es einsetzt.

Wenn Sie in PHP mit der mysqli-Erweiterung ein SELECT ausführen, muss MySQL die passenden Zeilen an Ihr Skript zurückgeben. Es gibt zwei Möglichkeiten, diese zu empfangen: gepuffert (die gesamte Ergebnismenge auf einmal in den PHP-Speicher kopieren) und ungepuffert (die Zeilen auf dem MySQL-Server belassen und sie einzeln abrufen). Die Funktion mysqli_use_result() initiiert den ungepufferten Modus.

Dieser Leitfaden erklärt, was mysqli_use_result() tut, wie es sich vom standardmäßigen gepufferten Modus unterscheidet, welche Regeln beim Einsatz zu beachten sind und wann es sich tatsächlich lohnt.

Was mysqli_use_result() tut

mysqli_use_result() initiiert den Abruf einer Ergebnismenge, die durch eine Abfrage erzeugt wurde, ohne die Zeilen in den PHP-Speicher zu kopieren. Anstatt alle Zeilen vorab herunterzuladen, behält der Server die Zeilen und Ihr Skript ruft sie einzeln beim Durchlaufen der Schleife ab.

Vergleichen Sie das mit dem Standardverhalten. Wenn Sie mysqli_query() aufrufen, ruft mysqli intern mysqli_store_result() für Sie auf — es lädt die gesamte Ergebnismenge in den Client-Speicher, bevor Ihr Code eine einzige Zeile sieht. Bei einer Abfrage, die zehn Millionen Zeilen zurückgibt, können das Hunderte von Megabytes PHP-Speicher sein. mysqli_use_result() vermeidet diese Kosten: Der Speicherverbrauch bleibt unabhängig von der Anzahl der zurückgegebenen Zeilen ungefähr konstant.

Syntax

mysqli_use_result(mysqli $mysql): mysqli_result|false

Die Funktion nimmt das Verbindungsobjekt (oder den Link) entgegen, das von mysqli_connect() zurückgegeben wird, und gibt bei Erfolg ein mysqli_result-Objekt zurück, oder false bei einem Fehler. Im objektorientierten Stil lautet die entsprechende Methode $mysqli->use_result().

Gepuffert vs. ungepuffert: Warum der Unterschied wichtig ist

Gepuffert (store_result)Ungepuffert (use_result)
Speicher auf PHP-SeiteHält die gesamte ErgebnismengeUngefähr eine Zeile auf einmal
mysqli_num_rows()Sofort verfügbarErst nach dem Abrufen aller Zeilen
mysqli_data_seek()UnterstütztNicht unterstützt
Die Verbindung während des LesensFrei für neue AbfragenGesperrt bis zum Abschluss
Am besten geeignet fürKleine/mittlere ErgebnismengenSehr große Ergebnismengen

Der wesentliche Kompromiss: Der ungepufferte Modus ist speicherschonend, belegt aber die Verbindung. Sie können auf derselben Verbindung keine weitere Abfrage ausführen, bis Sie alle Zeilen abgerufen (oder das Ergebnis freigegeben) haben. Der gepufferte Modus ist das Gegenteil — speicherintensiver, aber die Verbindung ist frei, sobald die Abfrage zurückkehrt.

So verwenden Sie mysqli_use_result()

1. Verbindung zum MySQL-Server herstellen

Öffnen Sie zuerst eine Verbindung mit mysqli_connect():

<?php

$host     = 'localhost';
$user     = 'username';
$password = 'password';
$database = 'mydatabase';

$connection = mysqli_connect($host, $user, $password, $database);

if (!$connection) {
    die('Connection failed: ' . mysqli_connect_error());
}

2. Abfrage ausführen und ungepuffertes Abrufen starten

Für den ungepufferten Modus müssen Sie die Abfrage ausführen, ohne mysqli aufzufordern, das Ergebnis zu speichern. Verwenden Sie das Flag MYSQLI_USE_RESULT mit mysqli_query() (oder rufen Sie mysqli_real_query() auf), und rufen Sie dann mysqli_use_result() auf:

$sql = "SELECT id, name FROM users";

// MYSQLI_USE_RESULT tells mysqli NOT to buffer the rows.
mysqli_real_query($connection, $sql);

$result = mysqli_use_result($connection);

if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        // Process one row at a time — only this row lives in PHP memory.
        print_r($row);
    }
    mysqli_free_result($result);
}

Jeder Aufruf von mysqli_fetch_assoc() holt die nächste Zeile direkt aus der Leitung. Sie können auf dieselbe Weise auch mysqli_fetch_row(), mysqli_fetch_array() oder mysqli_fetch_all() verwenden.

3. Ergebnis immer freigeben

Der Aufruf von mysqli_free_result() ist hier wichtiger als im gepufferten Modus: Bis das Ergebnis freigegeben (oder vollständig gelesen) ist, bleibt die Verbindung gesperrt und für andere Abfragen nicht verwendbar.

Regeln und Fallstricke

  • Alle Zeilen vor der nächsten Abfrage lesen. Solange ein ungepuffertes Ergebnis offen ist, ist die Verbindung beschäftigt. Der Versuch, eine weitere Abfrage auszuführen, bevor die Schleife abgeschlossen ist, löst einen „Commands out of sync"-Fehler aus. Schließen Sie die Schleife ab oder rufen Sie zuerst mysqli_free_result() auf.
  • Keine Zeilenanzahl im Voraus. mysqli_num_rows() gibt die korrekte Anzahl erst zurück, nachdem Sie alle Zeilen abgerufen haben, da der Server dem Client noch nicht mitgeteilt hat, wie viele es sind.
  • Kein wahlfreier Zugriff. mysqli_data_seek() funktioniert nicht bei ungepufferten Ergebnissen — Sie können sich nur vorwärts bewegen.
  • Ein Ergebnis pro Verbindung. Sie können auf einer Verbindung jeweils nur ein ungepuffertes Ergebnis offen halten.

Wann sollte man es verwenden?

Greifen Sie auf mysqli_use_result() zurück, wenn eine Abfrage weit mehr Daten zurückgibt, als Sie im Speicher halten möchten — z. B. beim Exportieren einer großen Tabelle als CSV, beim Streamen eines Berichts oder beim zeilenweisen Einspeisung eines langen Ergebnisses in einen anderen Prozess. In diesen Fällen ist der konstante Speicherverbrauch ein echter Vorteil.

Für alltägliche Abfragen, die eine Handvoll oder auch einige Tausend Zeilen zurückgeben, bleiben Sie beim standardmäßigen gepufferten Modus über mysqli_query(). Der Komfort von mysqli_num_rows(), wahlfreiem Zugriff und einer freien Verbindung überwiegt fast immer die bescheidene Speicherersparnis.

Fazit

mysqli_use_result() startet eine ungepufferte MySQL-Ergebnismenge und ruft Zeilen einzeln ab, sodass der Speicherverbrauch auch bei riesigen Ergebnismengen niedrig bleibt. Der Preis dafür ist, dass die Verbindung gesperrt ist, bis Sie das Lesen abgeschlossen haben, mysqli_num_rows() und mysqli_data_seek() nicht verfügbar sind und das Ergebnis umgehend freigegeben werden muss. Verwenden Sie es für wirklich große Datensätze; bevorzugen Sie den gepufferten Standard für gewöhnliche Abfragen.

Übung

Übung
Welche Möglichkeiten gibt es, ein Ergebnis aus MySQL in PHP zu verwenden?
Welche Möglichkeiten gibt es, ein Ergebnis aus MySQL in PHP zu verwenden?
Was this page helpful?