W3docs

next_result

Saiba como usar a função mysqli_next_result() do PHP para preparar o próximo conjunto de resultados de mysqli_multi_query().

Quando você envia várias instruções SQL ao MySQL em uma única chamada com mysqli_multi_query(), o servidor retorna os resultados um conjunto de cada vez. mysqli_next_result() é a função que avança do conjunto de resultados atual para o próximo, permitindo percorrer todos eles em um loop. Este artigo explica o que a função retorna, os parâmetros que aceita, os erros mais comuns e como utilizá-la nos estilos procedural e orientado a objetos do MySQLi.

O que mysqli_next_result() faz

mysqli_next_result() prepara o próximo conjunto de resultados de uma chamada anterior a mysqli_multi_query() e o disponibiliza para funções de recuperação como mysqli_store_result() ou mysqli_fetch_assoc(). Internamente, o MySQL armazena em buffer todos os conjuntos de resultados de uma multi-query; essa função avança o ponteiro interno em uma posição.

Importante: uma única chamada a mysqli_next_result() avança apenas um passo. Para processar todas as instruções, chame-a dentro de um loop até não restar mais resultados.

Sintaxe

// Procedural style
mysqli_next_result(mysqli $mysql): bool

// Object-oriented style
$mysqli->next_result(): bool

Parâmetros

  • $mysql (somente procedural) — o objeto de conexão retornado por mysqli_connect(). No estilo OOP, é o objeto sobre o qual o método é chamado.

Valor de retorno

Retorna um boolean:

  • true — o próximo conjunto de resultados foi preparado com sucesso (ou não havia mais resultados e nenhum erro ocorreu).
  • false — houve um erro na próxima instrução, ou a query anterior não tinha resultados em buffer para avançar.

Para distinguir "não há mais resultados" de "a próxima instrução falhou", use em conjunto com mysqli_more_results(): se mysqli_more_results() for true mas mysqli_next_result() retornar false, a próxima instrução gerou um erro.

Como usar mysqli_next_result() (estilo procedural)

Execute o lote com mysqli_multi_query(), processe o primeiro conjunto de resultados e, em seguida, faça um loop enquanto houver mais resultados, avançando com mysqli_next_result() a cada iteração:

<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");

if (!$mysqli) {
    die("Connection failed: " . mysqli_connect_error());
}

$query  = "SELECT name FROM users LIMIT 1;";
$query .= "SELECT title FROM posts LIMIT 1;";

if (mysqli_multi_query($mysqli, $query)) {
    do {
        // mysqli_store_result() returns false for statements that
        // produce no rows (INSERT, UPDATE, DELETE), so guard with if.
        if ($result = mysqli_store_result($mysqli)) {
            while ($row = mysqli_fetch_assoc($result)) {
                print_r($row);
            }
            mysqli_free_result($result);
        }
        // Stop when there are no more results; otherwise advance.
    } while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
} else {
    echo "Multi-query failed: " . mysqli_error($mysqli);
}

mysqli_close($mysqli);
?>

A condição do do...while é a ideia central: mysqli_more_results() verifica se existe outro conjunto, e mysqli_next_result() avança para ele. Como && usa avaliação em curto-circuito, mysqli_next_result() só é chamada quando realmente existe outro resultado, evitando o aviso que ocorreria ao chamá-la após o último conjunto.

Estilo orientado a objetos

A mesma lógica com a API OOP fica um pouco mais limpa:

<?php
$mysqli = new mysqli("localhost", "username", "password", "database");

if ($mysqli->connect_errno) {
    die("Connection failed: " . $mysqli->connect_error);
}

$sql  = "SELECT name FROM users LIMIT 1;";
$sql .= "SELECT title FROM posts LIMIT 1;";

if ($mysqli->multi_query($sql)) {
    do {
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_assoc()) {
                print_r($row);
            }
            $result->free();
        }
    } while ($mysqli->more_results() && $mysqli->next_result());
}

$mysqli->close();
?>

Erros comuns

  • Sempre esvazie a fila. Se você executar outra query enquanto conjuntos de resultados de um mysqli_multi_query() anterior ainda estiverem pendentes, o MySQLi lançará "Commands out of sync". Faça um loop com mysqli_next_result() até que mysqli_more_results() seja false antes de emitir uma nova query.
  • Esquecer mysqli_store_result() para instruções não-SELECT. Instruções como INSERT não produzem conjunto de resultados, então mysqli_store_result() retorna false — isso é esperado, não é um erro. A proteção com if ($result = ...) trata esse caso.
  • Multi-query é um risco de injeção SQL. Passe apenas SQL confiável e controlado pelo servidor para mysqli_multi_query(). Nunca concatene entrada do usuário em uma string de múltiplas instruções; use prepared statements para dados do usuário.

Conclusão

mysqli_next_result() é a função que permite percorrer todos os conjuntos de resultados retornados por uma única chamada a mysqli_multi_query(). Usada em conjunto com mysqli_more_results() dentro de um loop do...while, permite processar a saída de cada instrução com segurança e mantém a conexão sincronizada. Para mais informações sobre o fluxo de trabalho relacionado, consulte mysqli_multi_query() e mysqli_fetch_assoc().

Prática

Prática
O que a função PHP mysqli::next_result faz?
O que a função PHP mysqli::next_result faz?
Was this page helpful?