Me doy cuenta de que ha pasado un tiempo desde que hubo alguna actividad nueva sobre esta cuestión. Pero, como han comentado otros carteles, get_result()
ahora solo está disponible en PHP mediante la instalación del controlador nativo de MySQL (mysqlnd) y, en algunos casos, puede que no sea posible o deseable instalar mysqlnd. Entonces, pensé que sería útil publicar esta respuesta con información sobre cómo obtener la funcionalidad que get_result()
ofrece, sin usarget_result()
.
get_result()
es / se combinó a menudo con fetch_array()
para recorrer un conjunto de resultados y almacenar los valores de cada fila del conjunto de resultados en una matriz asociativa o indexada numéricamente. Por ejemplo, el siguiente código usa get_result () con fetch_array () para recorrer un conjunto de resultados, almacenando los valores de cada fila en la matriz $ data [] indexada numéricamente:
$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";
}
Sin embargo, si get_result()
no está disponible (porque mysqlnd no está instalado), esto lleva al problema de cómo almacenar los valores de cada fila de un conjunto de resultados en una matriz, sin usar get_result()
. O cómo migrar el código heredado que solía get_result()
ejecutarse sin él (por ejemplo, usarlo en su bind_result()
lugar), mientras afecta al resto del código lo menos posible.
Resulta que almacenar los valores de cada fila en una matriz indexada numéricamente no es tan sencillo de usar bind_result()
. bind_result()
espera una lista de variables escalares (no una matriz). Por lo tanto, se necesita algo de esfuerzo para que almacene los valores de cada fila del conjunto de resultados en una matriz.
Por supuesto, el código podría modificarse fácilmente de la siguiente manera:
$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";
}
Pero, esto requiere que enumeremos explícitamente $ data [0], $ data [1], etc. individualmente en la llamada a bind_result()
, lo cual no es ideal. Queremos una solución que no requiera que tengamos que enumerar explícitamente $ datos [0], $ datos [1], ... $ datos [N-1] (donde N es el número de campos en la declaración de selección) en la llamada a bind_results()
. Si estamos migrando una aplicación heredada que tiene una gran cantidad de consultas, y cada consulta puede contener una cantidad diferente de campos en elselect
cláusula, la migración será muy laboriosa y propensa a errores si usamos una solución como la anterior. .
Idealmente, queremos un fragmento de código de 'reemplazo directo', para reemplazar solo la línea que contiene la get_result()
función y el bucle while () en la siguiente línea. El código de reemplazo debe tener la misma función que el código que está reemplazando, sin afectar ninguna de las líneas anteriores o posteriores, incluidas las líneas dentro del bucle while (). Idealmente, queremos que el código de reemplazo sea lo más compacto posible, y no queremos tener que adaptar el código de reemplazo en función del número de campos en elselect
cláusula de la consulta.
Buscando en Internet, encontré una serie de soluciones que se utilizan bind_param()
con call_user_func_array()
(por ejemplo, enlazar dinámicamente los parámetros mysqli_stmt y luego enlazar el resultado (PHP) ), pero la mayoría de las soluciones que encontré finalmente conducen a que los resultados se almacenen en una matriz asociativa, no una matriz indexada numéricamente, y muchas de estas soluciones no eran tan compactas como me gustaría y / o no eran adecuadas como 'reemplazos directos'. Sin embargo, a partir de los ejemplos que encontré, pude improvisar esta solución, que se ajusta a los requisitos:
$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";
}
Por supuesto, el ciclo for () se puede contraer en una línea para hacerlo más compacto.
Espero que esto ayude a cualquiera que esté buscando una solución que utilice bind_result()
para almacenar los valores de cada fila en una matriz indexada numéricamente y / o busque una forma de migrar el código heredado usando get_result()
. Comentarios bienvenidos.
$stmt = $conn->mysqli->stmt_init();
?