Hallo Tom,
...und neuem Request an die Datenbank, ohne das Resultset wieder freizugeben.
Nein, das passiert hier nicht. Da die gleiche Variable wieder überschrieben wird, wird das alte Result-Set durchaus freigegeben, PHP macht das beim Vernichten der Resource automatisch. Du solltest nicht über das Ziel hinausschießen und (wenn auch unabsichtlich) Fehlinformationen verbreiten, wenn Du schlechten Code kritisierst, das ist auf Lange sicht nämlich auch nicht hilfreich. Daher mal als Merksatz:
Wenn man bei PHP irgend eine Art Handle hat (Resource für Datenbankverbindung, Datenbankresult, Datei, ... oder mit neueren APIs à la PDO eben Objekte statt Resourcen) und dieses Handle wird nicht mehr benötigt (weil es eben mit keiner Variable mehr fest verbunden ist), dann kümmert sich PHP alleine um das Aufräumen des Handles. Genauer gesagt ruft PHP nur eine von der Erweiterung vorher festgelegte Funktion auf, die das dann erledigt. In fast allen Fällen sind Funktionen wie mysql_free_result() überflüssig. Es gibt Ausnahmen, aber die treten bei typischer Verwendung von solchen Dingen sehr selten auf.
Um das mal zu erläutern:
for ($i = 0; $i < 100; $i++) {
$result = mysql_query ("SELECT * FROM foobar");
}
Am Anfang der Schleife ist $result NULL. Wenn die erste Iteration der Schleife vorbei ist, ist $result ein Zeiger auf das erste Result-Set. Wenn nun die Schleife das nächste mal iteriert wird, will PHP $result überschreiben. Dabei gibt PHP das frei, was vorher in $result enthalten war, nämlich das erste Result-Set. Danach erst wird das zweite Result-Set an die Variable zugewiesen. Man hat also zeitgleich nur zwei Resultsets herumflattern (das alte + ein neues, das Resultat von mysql_query ist, was noch in irgend einer temporären Kiste rumfliegt, bevor es zugewiesen wird) - und bestimmt keine 100. Hier ist es absolut nicht nötig, das alte Result-Set wieder freizugeben.
Anderes Beispiel:
function foobar () {
$result = mysql_query ("SELECT * FROM foobar");
return mysql_fetch_row ($result);
}
Auch hier ist es nicht nötig, das Result-Set explizit wieder freizugeben. Denn am Ende der Funktion wird die Variable $result zerstört und damit die letzte Referenz auf das Result-Set -> PHP erledigt das automatisch.
Weiteres Beispiel:
$row = mysql_fetch_row (
mysql_query ("SELECT * FROM foobar")
);
Auch hier ist es nicht nötig, das Result-Set explizit wieder freizugeben: Das Ergebnis von mysql_query wird sowieso nur temporär im Speicher behalten und am Ende des Aufrufs von mysql_fetch_row wird das Result-Set automatisch wieder freigegeben, weil's nirgendwo mehr referenziert wird.
Wo es dagegen wirklich nötig ist, das Result-Set explizit wieder freizugeben ist in Fällen, in denen man sich nicht sicher sein kann, das das Result-Set nicht auch woanders noch referenziert wird - z.B. wenn man weitere Referenzen in irgendwelchen anderen Variablen speichert (aus welchen Gründen auch immer) und man sich nicht darauf verlassen will, dass diese anderen Variablen auch immer aus dem Scope geraten. Mir fällt jedoch ad-hoch kein sinnvolles Beispiel ein, wo dies nötig sein könnte, ich wollte es nur der Vollständigkeit halber mal erwähnen. Das ändert jedoch nichts an der Tatsache, dass dies in den meisten Fällen nicht nötig ist.
Dies soll selbstverständlich nicht heißen, dass die Beispiele in meinem Posting nicht trotzdem schlechter Code sind - aber das sind sie eben aus anderen Gründen, nicht wegen irgendwelchen Dingen, die angeblich noch im Speicher herumgeistern. Diese Gründe wären vor allem mangelnde Fehlerbehandlung (es wird nicht geprüft ob mysql_query überhaupt erfolgreich ist und ein Result-Set zurückliefert) und zumindest im ersten Beispiel ist es extrem fraglich, ob es effizient ist, den gleichen Query in einer Schleife wiederholt auszuführen.
Viele Grüße,
Christian
Mein "Weblog" [RSS]
Using XSLT to create JSON output (Saxon-B 9.0 for Java)
»I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
-- Kommentar bei TDWTF