Percebo que já faz um tempo que não houve qualquer nova atividade sobre essa questão. Mas, como outros participantes comentaram - get_result()
agora está disponível apenas em PHP com a instalação do driver nativo MySQL (mysqlnd) e, em alguns casos, pode não ser possível ou desejável instalar mysqlnd. Então, achei que seria útil postar esta resposta com informações sobre como obter a funcionalidade que get_result()
oferece - sem usar get_result()
.
get_result()
é / era frequentemente combinado com fetch_array()
para percorrer um conjunto de resultados e armazenar os valores de cada linha do conjunto de resultados em uma matriz indexada numericamente ou associativa. Por exemplo, o código a seguir usa get_result () com fetch_array () para percorrer um conjunto de resultados, armazenando os valores de cada linha no array $ data [] indexado 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";
}
No entanto, se get_result()
não estiver disponível (porque mysqlnd não está instalado), isso levará ao problema de como armazenar os valores de cada linha de um conjunto de resultados em um array, sem usar get_result()
. Ou como migrar o código legado que usa get_result()
para ser executado sem ele (por exemplo, usando ao bind_result()
invés) - enquanto afeta o resto do código o mínimo possível.
Acontece que armazenar os valores de cada linha em uma matriz indexada numericamente não é tão simples de usar bind_result()
. bind_result()
espera uma lista de variáveis escalares (não uma matriz). Portanto, é necessário algum esforço para armazená-los em um array os valores de cada linha do conjunto de resultados.
Claro, o código pode ser facilmente modificado da seguinte maneira:
$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";
}
Mas, isso exige que listemos explicitamente $ data [0], $ data [1], etc. individualmente na chamada para bind_result()
, o que não é o ideal. Queremos uma solução que não exija que listemos explicitamente $ data [0], $ data [1], ... $ data [N-1] (onde N é o número de campos na instrução select) na chamada para bind_results()
. Se estivermos migrando um aplicativo legado que tem um grande número de consultas e cada consulta pode conter um número diferente de campos na select
cláusula, a migração será muito trabalhosa e sujeita a erros se usarmos uma solução como a acima .
Idealmente, queremos um snippet de código de 'substituição drop-in' - para substituir apenas a linha que contém a get_result()
função e o loop while () na próxima linha. O código de substituição deve ter a mesma função do código que está substituindo, sem afetar nenhuma das linhas anteriores ou posteriores - incluindo as linhas dentro do loop while (). Idealmente, queremos que o código de substituição seja o mais compacto possível e não queremos ter que ajustar o código de substituição com base no número de campos na select
cláusula da consulta.
Pesquisando na internet, encontrei uma série de soluções que usam bind_param()
com call_user_func_array()
(por exemplo, vincular dinamicamente os parâmetros mysqli_stmt e depois vincular o resultado (PHP) ), mas a maioria das soluções que encontrei eventualmente levam ao armazenamento dos resultados em uma matriz associativa, não uma matriz indexada numericamente, e muitas dessas soluções não eram tão compactas quanto eu gostaria e / ou não eram adequadas como 'substituições imediatas'. No entanto, a partir dos exemplos que encontrei, fui capaz de remendar esta solução, que se encaixa no projeto:
$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";
}
Claro, o loop for () pode ser reduzido em uma linha para torná-lo mais compacto.
Espero que isso ajude quem está procurando uma solução usando bind_result()
para armazenar os valores de cada linha em uma matriz indexada numericamente e / ou procurando uma maneira de migrar o código legado usando get_result()
. Comentários são bem-vindos.
$stmt = $conn->mysqli->stmt_init();
?