Onkel Schnitzel: Ressource aus mysql_query() mehrfach nutzen

Hallihallo,

wird eigentlich eine Ressource aus

$anfrage = mysql_query($sql);

die ich mit while($auslesen = mysql_fetch_assoc($anfrage)) {... anfrage und ausgebe, eigentlich danach aus dem Speicher gelöscht? Denn wenn ich sie versuche, mit while($auslesen2 = mysql_fetch_assoc($anfrage)) {... ein zweites Mal zu nutzen, bekomme ich ein leeres Ergebnis zurück.

Es geht nur darum, dass ich das Ergebnis einer DB-Abfrage zweimal benötige. Ich könnte mir das Ergebnis natürlich auch in einem eigenen Array zwischenspeichern, aber ich dachte es geht vielleicht auch über meine Methode. Aber offensichtlich ja nicht, oder?

Gruß

Onkel Schnitzel

  1. Tach!

    wird eigentlich eine Ressource aus
    $anfrage = mysql_query($sql);
    die ich mit while($auslesen = mysql_fetch_assoc($anfrage)) {... anfrage und ausgebe, eigentlich danach aus dem Speicher gelöscht?

    Nein. Die Ergebnismenge wird jedoch bereits beim mysql_query() komplett in den Speicher übertragen. Das Fetchen findet nur noch im lokalen Speicher statt. Zum Beispiel kann auch die Funktion mysql_num_rows() nur deshalb sofort nach der Query sagen, wieviele Ergebniszeilen es gibt.

    Denn wenn ich sie versuche, mit while($auslesen2 = mysql_fetch_assoc($anfrage)) {... ein zweites Mal zu nutzen, bekomme ich ein leeres Ergebnis zurück.

    Wenn du am Ende der Ergebnismenge angelangt bist, liefern die Fetch-Funktionen false, egal wie oft sie noch aufgerufen werden. Wenn du von vorn anfangen möchtest, musst du erst einmal den Ergebniszeiger wieder auf 0 setzen: mysql_data_seek().

    Es geht nur darum, dass ich das Ergebnis einer DB-Abfrage zweimal benötige. Ich könnte mir das Ergebnis natürlich auch in einem eigenen Array zwischenspeichern, aber ich dachte es geht vielleicht auch über meine Methode.

    Ein eigenes Array wäre auch eine Möglichkeit, ohne dass (seit PHP 5.3) wesentlich mehr Speicher verwendet wird. PHP kopiert nämlich Werte nicht physisch, solange sie nicht auseinanderlaufen.

    $a = 'foo';
    $b = $a;

    belegt nur einmal Speicher für 'foo'. $b ist PHP-intern eine Referenz auf $a. Erst wenn $b verändert wird, wird separater Speicher verwendet. Das nennt sich Copy on Write. Der seit 5.3 hinzugekommene Treiber mysqlnd (auf dem mysql und mysqli seitdem aufsetzen) nutzt nun für die Ergebnismenge PHP-typischen Variablenspeicher und keinen eigenen Bereich, so dass das Copy-on-Write-Prinzip angewendet werden kann. Mit anderen Worten, das "Kopieren" der Fetch-Menge in ein Array benötigt nur für die Array-Verwaltung an sich zusätzlichen Speicher, nicht jedoch für die DB-Daten.

    dedlfix.

    1. Hallo,

      ich habe mich für die einfache Variante entschieden und den Zeiger auf 0 gesetzt, das hat funktioniert. Da du ja meintest, die Ergebnismenge befindet sich schon bzw. noch im Speicher, ist ja diese Variante genauso ressourcenschonend wie die Array-Variante (interessante Info übrigens zum Speichermanagement). Auf jeden Fall vermeide ich somit eine doppelte DB-Abfrage, und das wollte ich erreichen.

      Vielen Dank!

      Gruß

      Onkel Schnitzel

  2. Hallo,

    Es geht nur darum, dass ich das Ergebnis einer DB-Abfrage zweimal benötige. Ich könnte mir das Ergebnis natürlich auch in einem eigenen Array zwischenspeichern, aber ich dachte es geht vielleicht auch über meine Methode. Aber offensichtlich ja nicht, oder?

    Du könntest Dir mal mysql_data_seek angucken. Damit kannst Du den Ergebniszeiger wieder zurücksetzen.

    Hab damit noch nicht gearbeitet, aber theoretisch müsste damit das gewünschte gehen.

    Hope that helps,

    Jörg