W3docs

next_result

Aprende a usar la función mysqli_next_result() en PHP para preparar el siguiente conjunto de resultados tras mysqli_multi_query().

Cuando envías varias sentencias SQL a MySQL en una sola llamada con mysqli_multi_query(), el servidor te devuelve los resultados de a un conjunto a la vez. mysqli_next_result() es la función que te permite pasar del conjunto de resultados actual al siguiente, para que puedas recorrerlos todos. Este artículo explica qué devuelve la función, los parámetros que acepta, los errores más comunes y cómo usarla tanto en el estilo procedimental como en el orientado a objetos de MySQLi.

Qué hace mysqli_next_result()

mysqli_next_result() prepara el siguiente conjunto de resultados de una llamada previa a mysqli_multi_query() y lo deja disponible para funciones de recuperación como mysqli_store_result() o mysqli_fetch_assoc(). Internamente, MySQL almacena en búfer todos los conjuntos de resultados de una consulta múltiple; esta función avanza el puntero interno en una posición.

Importante: una sola llamada a mysqli_next_result() solo avanza un paso. Para procesar todas las sentencias, debes llamarla dentro de un bucle hasta que no queden más resultados.

Sintaxis

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

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

Parámetros

  • $mysql (solo estilo procedimental) — el objeto de conexión devuelto por mysqli_connect(). En el estilo OOP, es el objeto sobre el que se llama el método.

Valor de retorno

Devuelve un boolean:

  • true — el siguiente conjunto de resultados se preparó correctamente (o no había más resultados y no hubo error).
  • false — hubo un error en la siguiente sentencia, o la consulta anterior no tenía resultados en búfer a los que avanzar.

Para distinguir "no hay más resultados" de "la siguiente sentencia falló", combínalo con mysqli_more_results(): si mysqli_more_results() devuelve true pero mysqli_next_result() devuelve false, la siguiente sentencia generó un error.

Cómo usar mysqli_next_result() (estilo procedimental)

Ejecuta el lote con mysqli_multi_query(), procesa el primer conjunto de resultados y luego itera mientras haya más, avanzando con mysqli_next_result() en cada pasada:

<?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);
?>

La condición do...while es la idea clave: mysqli_more_results() comprueba si existe otro conjunto, y mysqli_next_result() avanza realmente hasta él. Gracias a la evaluación en cortocircuito de &&, mysqli_next_result() solo se llama cuando realmente existe otro resultado, lo que evita la advertencia que se produciría al llamarla después del último conjunto.

Estilo orientado a objetos

La misma lógica con la API OOP resulta un poco más limpia:

<?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();
?>

Errores comunes

  • Vaciar siempre la cola. Si ejecutas otra consulta mientras aún hay conjuntos de resultados pendientes de un mysqli_multi_query() anterior, MySQLi lanza "Commands out of sync". Itera con mysqli_next_result() hasta que mysqli_more_results() sea false antes de emitir una nueva consulta.
  • Olvidar mysqli_store_result() para sentencias que no son SELECT. Sentencias como INSERT no producen ningún conjunto de resultados, por lo que mysqli_store_result() devuelve false — eso es lo esperado, no un error. El guard if ($result = ...) lo maneja.
  • Multi-query es un riesgo de inyección SQL. Solo pasa a mysqli_multi_query() SQL de confianza y controlado por el servidor. Nunca concatenes entrada del usuario en una cadena de múltiples sentencias; usa sentencias preparadas para los datos del usuario.

Conclusión

mysqli_next_result() es la función que te permite recorrer todos los conjuntos de resultados devueltos por una sola llamada a mysqli_multi_query(). Usada junto con mysqli_more_results() dentro de un bucle do...while, te permite procesar la salida de cada sentencia de forma segura y evita que la conexión quede fuera de sincronía. Para más información sobre el flujo de trabajo, consulta mysqli_multi_query() y mysqli_fetch_assoc().

Práctica

Práctica
¿Qué hace la función PHP mysqli::next_result?
¿Qué hace la función PHP mysqli::next_result?
Was this page helpful?