Mir ist klar, dass es eine Weile her ist, dass es zu dieser Frage neue Aktivitäten gegeben hat. Aber, wie andere Poster kommentiert haben, get_result()
ist es jetzt nur in PHP verfügbar, indem der native MySQL-Treiber (mysqlnd) installiert wird. In einigen Fällen ist es möglicherweise nicht möglich oder wünschenswert, mysqlnd zu installieren. Daher dachte ich, es wäre hilfreich, diese Antwort mit Informationen darüber zu veröffentlichen, wie Sie die angebotenen Funktionen erhalten get_result()
- ohne sie zu verwenden get_result()
.
get_result()
wird / wurde oft kombiniert fetch_array()
, um eine Ergebnismenge zu durchlaufen und die Werte aus jeder Zeile der Ergebnismenge in einem numerisch indizierten oder assoziativen Array zu speichern. Im folgenden Code wird beispielsweise get_result () mit fetch_array () verwendet, um eine Ergebnismenge zu durchlaufen und die Werte aus jeder Zeile im numerisch indizierten Array $ data [] zu speichern:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$result = $stmt->get_result();
while($data = $result->fetch_array(MYSQLI_NUM)) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Wenn dies get_result()
jedoch nicht verfügbar ist (da mysqlnd nicht installiert ist), führt dies zu dem Problem, wie die Werte aus jeder Zeile einer Ergebnismenge in einem Array ohne Verwendung gespeichert werden können get_result()
. Oder wie man alten Code migriert, der verwendet wird get_result()
, um ohne ihn ausgeführt zu werden (z. B. bind_result()
stattdessen), während der Rest des Codes so wenig wie möglich beeinflusst wird.
Es stellt sich heraus, dass das Speichern der Werte aus jeder Zeile in einem numerisch indizierten Array nicht so einfach ist bind_result()
. bind_result()
erwartet eine Liste skalarer Variablen (kein Array). Es ist also einige Arbeit erforderlich, um die Werte aus jeder Zeile der Ergebnismenge in einem Array zu speichern.
Natürlich kann der Code leicht wie folgt geändert werden:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Dies erfordert jedoch, dass wir $ data [0], $ data [1] usw. im Aufruf von explizit einzeln auflisten bind_result()
, was nicht ideal ist. Wir wollen eine Lösung, bei der wir nicht explizit $ data [0], $ data [1], ... $ data [N-1] auflisten müssen (wobei N die Anzahl der Felder in der select-Anweisung ist). im Anruf an bind_results()
. Wenn wir eine Legacy-Anwendung mit einer großen Anzahl von Abfragen migrieren und jede Abfrage möglicherweise eine andere Anzahl von Feldern in der select
Klausel enthält, ist die Migration sehr arbeitsintensiv und fehleranfällig, wenn wir eine Lösung wie die oben beschriebene verwenden .
Idealerweise möchten wir einen Ausschnitt aus dem Drop-In-Ersetzungscode, um nur die Zeile zu ersetzen, die die get_result()
Funktion und die while () -Schleife in der nächsten Zeile enthält. Der Ersetzungscode sollte dieselbe Funktion haben wie der Code, den er ersetzt, ohne die Zeilen davor oder die Zeilen danach zu beeinflussen - einschließlich der Zeilen innerhalb der while () - Schleife. Idealerweise möchten wir, dass der Ersatzcode so kompakt wie möglich ist, und wir möchten nicht, dass der Ersatzcode basierend auf der Anzahl der Felder in der select
Klausel der Abfrage angepasst wird.
Bei der Suche im Internet habe ich eine Reihe von Lösungen gefunden, die bind_param()
mit call_user_func_array()
(z. B. dynamisch mysqli_stmt-Parameter binden und dann Ergebnis binden (PHP) ) verwendet werden. Die meisten Lösungen, die ich gefunden habe, führen jedoch dazu, dass die Ergebnisse in einem assoziativen Array gespeichert werden, nicht ein numerisch indiziertes Array, und viele dieser Lösungen waren nicht so kompakt, wie ich es gerne hätte, und / oder waren nicht als "Drop-In-Ersatz" geeignet. Aus den Beispielen, die ich gefunden habe, konnte ich jedoch diese Lösung zusammenschustern, die der Rechnung entspricht:
$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $c);
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) {
$var = $i;
$$var = null;
$data[$var] = &$$var;
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
print $data[0] . ', ' . $data[1] . "<BR>\n";
}
Natürlich kann die for () - Schleife in einer Zeile zusammengefasst werden, um sie kompakter zu machen.
Ich hoffe, dies hilft jedem, der nach einer Lösung sucht, mit der bind_result()
er die Werte aus jeder Zeile in einem numerisch indizierten Array speichert und / oder nach einer Möglichkeit sucht, Legacy-Code mithilfe von zu migrieren get_result()
. Kommentare willkommen.
$stmt = $conn->mysqli->stmt_init();
?