PHP mysqli_use_result() — Conjuntos de Resultados Não Armazenados em Buffer
Aprenda como mysqli_use_result() inicia um conjunto de resultados MySQL sem buffer, diferenças em relação a mysqli_store_result() e quando utilizá-la.
Ao executar um SELECT em PHP com a extensão mysqli, o MySQL precisa retornar as linhas correspondentes ao seu script. Existem duas formas de recebê-las: com buffer (copiar o resultado inteiro para a memória do PHP de uma só vez) e sem buffer (deixar as linhas no servidor MySQL e buscá-las uma a uma). A função mysqli_use_result() inicia o modo sem buffer.
Este guia explica o que mysqli_use_result() faz, como ela difere do modo com buffer padrão, as regras que você deve seguir ao utilizá-la e quando realmente vale a pena usá-la.
O que mysqli_use_result() faz
mysqli_use_result() inicia a recuperação de um conjunto de resultados produzido por uma consulta, sem copiar as linhas para a memória do PHP. Em vez de baixar todas as linhas antecipadamente, o servidor mantém as linhas e seu script as busca uma a uma conforme você percorre o loop.
Compare com o comportamento padrão. Quando você chama mysqli_query(), o mysqli internamente chama mysqli_store_result() — ele carrega o conjunto de resultados inteiro na memória do cliente antes que seu código veja uma única linha. Para uma consulta que retorna dez milhões de linhas, isso pode significar centenas de megabytes de memória PHP. mysqli_use_result() evita esse custo: o uso de memória permanece aproximadamente constante, independentemente do número de linhas retornadas pela consulta.
Sintaxe
mysqli_use_result(mysqli $mysql): mysqli_result|falseEla recebe o objeto de conexão (ou link) retornado por mysqli_connect() e retorna um objeto mysqli_result em caso de sucesso, ou false em caso de falha. No estilo orientado a objetos, o método equivalente é $mysqli->use_result().
Com buffer vs. sem buffer: por que a distinção importa
Com buffer (store_result) | Sem buffer (use_result) | |
|---|---|---|
| Memória no lado do PHP | Contém o conjunto de resultados inteiro | Aproximadamente uma linha por vez |
mysqli_num_rows() | Disponível imediatamente | Somente após buscar todas as linhas |
mysqli_data_seek() | Suportado | Não suportado |
| A conexão durante a leitura | Livre para novas consultas | Bloqueada até terminar |
| Melhor para | Conjuntos de resultados pequenos/médios | Conjuntos de resultados muito grandes |
O principal compromisso: o modo sem buffer consome pouca memória, mas ocupa a conexão. Você não pode executar outra consulta na mesma conexão até que tenha buscado todas as linhas (ou liberado o resultado). O modo com buffer é o oposto — consome mais memória, mas a conexão fica livre no momento em que a consulta retorna.
Como usar mysqli_use_result()
1. Conectar ao servidor MySQL
Primeiro, abra uma conexão com mysqli_connect():
<?php
$host = 'localhost';
$user = 'username';
$password = 'password';
$database = 'mydatabase';
$connection = mysqli_connect($host, $user, $password, $database);
if (!$connection) {
die('Connection failed: ' . mysqli_connect_error());
}2. Executar a consulta e iniciar a recuperação sem buffer
Para o modo sem buffer, você deve executar a consulta sem pedir ao mysqli que armazene o resultado. Use o sinalizador MYSQLI_USE_RESULT com mysqli_query() (ou chame mysqli_real_query()), e depois chame mysqli_use_result():
$sql = "SELECT id, name FROM users";
// MYSQLI_USE_RESULT tells mysqli NOT to buffer the rows.
mysqli_real_query($connection, $sql);
$result = mysqli_use_result($connection);
if ($result) {
while ($row = mysqli_fetch_assoc($result)) {
// Process one row at a time — only this row lives in PHP memory.
print_r($row);
}
mysqli_free_result($result);
}Cada chamada a mysqli_fetch_assoc() busca a próxima linha diretamente da rede. Você também pode usar mysqli_fetch_row(), mysqli_fetch_array() ou mysqli_fetch_all() da mesma forma.
3. Sempre libere o resultado
Chamar mysqli_free_result() é mais importante aqui do que no modo com buffer: enquanto o resultado não for liberado (ou totalmente lido), a conexão permanece bloqueada e inutilizável para qualquer outra consulta.
Regras e armadilhas
- Leia todas as linhas antes da próxima consulta. Enquanto um resultado sem buffer estiver aberto, a conexão está ocupada. Tentar executar outra consulta antes de terminar o loop gera um erro "Commands out of sync". Termine o loop ou chame
mysqli_free_result()primeiro. - Sem contagem de linhas antecipada.
mysqli_num_rows()retorna o número correto somente após você ter buscado todas as linhas, pois o servidor ainda não informou ao cliente quantas existem. - Sem acesso aleatório.
mysqli_data_seek()não funciona com resultados sem buffer — você só pode avançar. - Um resultado por conexão. Você pode manter apenas um resultado sem buffer aberto em uma conexão por vez.
Quando usar mysqli_use_result()?
Recorra a mysqli_use_result() quando uma consulta retorna muito mais dados do que você deseja manter na memória — como exportar uma tabela grande para CSV, transmitir um relatório ou alimentar um resultado longo linha a linha em outro processo. Nesses casos, o consumo constante de memória é uma vantagem real.
Para consultas do dia a dia que retornam alguns, ou mesmo alguns milhares de linhas, use o modo com buffer padrão via mysqli_query(). A conveniência de mysqli_num_rows(), a busca aleatória e uma conexão livre quase sempre supera a modesta economia de memória.
Conclusão
mysqli_use_result() inicia um conjunto de resultados MySQL sem buffer, buscando linhas uma a uma para que o uso de memória permaneça baixo mesmo para grandes conjuntos de resultados. O custo é que a conexão fica bloqueada até você terminar de ler, você perde mysqli_num_rows() e mysqli_data_seek(), e deve liberar o resultado prontamente. Use-a para conjuntos de dados genuinamente grandes; prefira o padrão com buffer para consultas comuns.