Hallo Barksalot,
der Unterschied ist, dass die alte Lösung mit data binding arbeitet, und die von Regina vorgeschlagene Lösung die "klassische" Fetch-Technik verwendet.
Data binding sieht für jede Spalte des Ergebisses eine Variable vor, in der der Inhalt dieser Spalte nach einem fetch() bereitgestellt wird. Du musst natürlich aufpassen, dass dein bind_result genau zum SQL Statement passt. Das Binding ist Tipparbeit, du musst den bind_result-Befehl aufbauen und die gebundenen Variablen ins Ergebnisarray umkopieren. In deinem Fall ist das eigentlich nutzlos, weil deine Array-Indexe genauso heißen wie die Spalten. D.h. das Ergebnis deines Codes ist das gleiche wie ein fetch_assoc und deswegen hat Regina das auch dahin geändert.
Binding gab es im klassischen mysql/mysqli nicht, da verwendete man fetch_row, fetch_assoc oder fetch_array, um sich die Trefferzeile als Array bereitstellen zu lassen. Unterschied zwischen den Funktionen ist, wie die Indexe des Arrays aussehen. Bei fetch_row ist es die Spaltennummer (erste Spalte ist Nr. 0), bei fetch_assoc der Spaltenname und bei fetch_array kannst Du es aussuchen (bzw. wenn Du nichts festlegst bekommst Du beides).
"Klassisch" heißen diese Funktionen mysqli_fetch_row, etc, und bekommen ein mysqli_result Objekt als Parameter. Objektorientiert sind es Methoden des mysqli_result Objekts. mysqli_query liefert Dir ein solches Objekt; es repräsentiert das Abfrageergebnis. Wenn Du mit prepare arbeitest, erzeugt stmt->execute() ein solches Objekt. Die stmt->fetch Methode verwendet es implizit; Du kannst es Dir aber mit $stmt->get_result() auch liefern lassen und damit auf Data Binding verzichten. Du solltest versuchen, Dir das alles im mysqli-Bereich der PHP Doku durchzulesen, auch wenn deine Augen streiken. Aber ich mache noch ein Beispiel:
Sei $sql = "SELECT A, B, C FROM SOMETABLE"
das SQL und die Trefferzeile enthalte A="foo", B=17 und C="abcde".
Das Result-Objekt bekommst Du entweder so:
// Ohne Prepare
$result = $mysqli->query($sql)
if ($result === FALSE) {
// Fehlerbehandlung
}
oder so:
// Mit Prepare
$stmt = $mysqli->prepare($sql);
if ($stmt === FALSE) { Fehlerbehandlung }
$ok = $stmt->execute();
if (!ok) { Fehlerbehandlung }
$result = $stmt->get_result();
if ($result === FALSE) { Fehlerbehandlung }
Natürlich kommt in der prepare-Variante noch ein bind_param hinzu, wenn das SQL Parameter braucht. Die Diskussion prepare vs query hatten wir schon öfter; query ist kompakter, dafür kannst Du Dir in den Fuß schießen wenn Du die Parameter unsauber ins Statement einbaust (Kontextwechsel-Problem). Bei prepare hilft Dir mysqli beim Kontextwechsel und es ist (vermutlich) effizienter, wenn Du die gleiche Query mit unterschiedlichen Parameterwerten ausführen musst. Dafür hast Du ein paar Zeilen Code mehr.
Die Ergebnisse der fetch-Varianten unterscheiden sich dann so:
$result->fetch_row()
ARRAY( 0 => "foo", 1 => 17, 2 => "abcde" )
$result->fetch_assoc()
ARRAY( "A" => "foo", "B" => 17, "C" => "abcde" )
$result->fetch_array()
ARRAY( 0 => "foo", 1 => 17, 2 => "abcde", "A" => "foo", "B" => 17, "C" => "abcde" )
$result->fetch_array(MYSQLI_NUM)
ARRAY( 0 => "foo", 1 => 17, 2 => "abcde" ) // wie fetch_row
$result->fetch_array(MYSQLI_ASSOC)
ARRAY( "A" => "foo", "B" => 17, "C" => "abcde" ) // wie fetch_assoc
Deswegen ist dein (äh, Reginas) Code kaputtgegangen, als da noch fetch_row stand. Welche der Aufrufvarianten du nimmst, hängt von deinen Vorlieben und vom Anwendungsfall ab.
Rolf
sumpsi - posui - clusi