Mi rendo conto che è passato un po 'di tempo da quando non c'è stata alcuna nuova attività su questa questione. Ma, come hanno commentato altri utenti, get_result()
ora è disponibile solo in PHP installando il driver nativo di MySQL (mysqlnd) e in alcuni casi potrebbe non essere possibile o desiderabile installare mysqlnd. Quindi, ho pensato che sarebbe stato utile pubblicare questa risposta con informazioni su come ottenere la funzionalità che get_result()
offre, senza utilizzare get_result()
.
get_result()
è / è stato spesso combinato con fetch_array()
per scorrere un set di risultati e memorizzare i valori di ciascuna riga del set di risultati in un array numerico o associativo. Ad esempio, il codice seguente utilizza get_result () con fetch_array () per scorrere un set di risultati, memorizzando i valori di ogni riga nell'array $ data [] indicizzato numericamente:
$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";
}
Tuttavia, se get_result()
non è disponibile (perché mysqlnd non è installato), allora questo porta al problema di come memorizzare i valori di ogni riga di un set di risultati in un array, senza utilizzare get_result()
. Oppure, come migrare il codice legacy che utilizza get_result()
per funzionare senza di esso (ad esempio utilizzandobind_result()
invece), influendo il meno possibile sul resto del codice.
Risulta che memorizzare i valori di ogni riga in una matrice indicizzata numericamente non è così semplice da usare bind_result()
. bind_result()
si aspetta un elenco di variabili scalari (non un array). Quindi, ci vuole un po 'di tempo per far sì che memorizzi i valori di ogni riga del set di risultati in un array.
Ovviamente il codice potrebbe essere facilmente modificato come segue:
$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";
}
Ma questo ci richiede di elencare esplicitamente $ data [0], $ data [1], ecc. Individualmente nella chiamata a bind_result()
, il che non è l'ideale. Vogliamo una soluzione che non richieda di dover elencare esplicitamente $ data [0], $ data [1], ... $ data [N-1] (dove N è il numero di campi nell'istruzione select) nella chiamata a bind_results()
. Se stiamo migrando un'applicazione legacy che ha un numero elevato di query e ogni query può contenere un numero diverso di campi nelselect
clausola, la migrazione sarà molto laboriosa e soggetta a errori se usiamo una soluzione come quella sopra .
Idealmente, vogliamo uno snippet di codice di "sostituzione immediata" - per sostituire solo la riga contenente la get_result()
funzione e il ciclo while () sulla riga successiva. Il codice sostitutivo dovrebbe avere la stessa funzione del codice che sta sostituendo, senza influenzare nessuna delle righe precedenti o successive, comprese le righe all'interno del ciclo while (). Idealmente vogliamo che il codice sostitutivo sia il più compatto possibile e non vogliamo dover adattare il codice sostitutivo in base al numero di campi nella select
clausola della query.
Cercando su Internet, ho trovato una serie di soluzioni che utilizzano bind_param()
con call_user_func_array()
(ad esempio, Associa dinamicamente i parametri mysqli_stmt e poi associa il risultato (PHP) ), ma la maggior parte delle soluzioni che ho trovato alla fine porta a memorizzare i risultati in un array associativo, non un array a indice numerico e molte di queste soluzioni non erano così compatte come avrei voluto e / o non erano adatte come "sostituzioni immediate". Tuttavia, dagli esempi che ho trovato, sono stato in grado di mettere insieme questa soluzione, che si adatta al conto:
$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";
}
Ovviamente, il ciclo for () può essere compresso in una riga per renderlo più compatto.
Spero che questo aiuti chiunque stia cercando una soluzione che utilizzi bind_result()
per memorizzare i valori di ogni riga in un array con indicizzazione numerica e / o che cerchi un modo per migrare il codice legacy utilizzando get_result()
. Commenti benvenuti.
$stmt = $conn->mysqli->stmt_init();
?