W3docs

data_seek

Aprende a usar mysqli_data_seek() en PHP para mover el puntero de resultado a una fila específica en un conjunto de resultados en memoria.

La función mysqli_data_seek() en PHP mueve el puntero de resultado interno a una fila arbitraria en un conjunto de resultados en búfer, de modo que la siguiente llamada de búsqueda lee desde esa fila en lugar de la siguiente secuencial. Permite saltar directamente a una fila, releer filas ya pasadas o reiniciar desde el principio sin ejecutar la consulta de nuevo. Los índices de fila son de base cero, y la función devuelve true en caso de éxito o false en caso de fallo.

Este capítulo cubre la firma de la función, tanto el estilo procedimental como el orientado a objetos, un ejemplo ejecutable, el requisito de resultado en búfer que confunde a la mayoría de las personas y cuándo SQL LIMIT … OFFSET es la herramienta más adecuada.

Sintaxis

// Procedural style
mysqli_data_seek(mysqli_result $result, int $offset): bool

// Object-oriented style
$result->data_seek(int $offset): bool
  • $result — un conjunto de resultados devuelto por mysqli_query(), mysqli_store_result() o mysqli_use_result().
  • $offset — el número de fila al que moverse, comenzando en 0 para la primera fila. Debe estar entre 0 y mysqli_num_rows() - 1.
  • Valor de retornotrue si el seek tiene éxito, false si el desplazamiento está fuera de rango o el conjunto de resultados no está en búfer.

El requisito de resultado en búfer

mysqli_data_seek() solo funciona en conjuntos de resultados en búfer — aquellos cuyas filas ya están almacenadas en memoria. Eso es lo que se obtiene de mysqli_query() (que llama a mysqli_store_result() internamente) y de mysqli_store_result() directamente.

Si se obtienen filas de forma diferida con mysqli_use_result(), las filas se transmiten desde el servidor de una en una y no hay nada en lo que buscar, por lo que mysqli_data_seek() fallará. Cuando se necesita acceso aleatorio, use un resultado en búfer.

Cómo usar mysqli_data_seek()

Llame a la función sobre un conjunto de resultados válido y pase el índice de fila al que quiere llegar. La siguiente búsqueda devolverá esa fila:

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

$result = mysqli_query($mysqli, "SELECT id, name FROM users ORDER BY id");

if (!$result) {
    echo "Failed to execute query: " . mysqli_error($mysqli);
    exit();
}

// Move the pointer to row 3 (index 2, because indices are zero-based)
if (!mysqli_data_seek($result, 2)) {
    echo "Seek failed";
    exit();
}

// Fetch the row the pointer now points at
$row = mysqli_fetch_assoc($result);

print_r($row);

mysqli_free_result($result);
mysqli_close($mysqli);
?>

Nos conectamos con mysqli_connect(), ejecutamos la consulta con mysqli_query() y comprobamos si hay errores. Luego mysqli_data_seek($result, 2) salta el puntero a la tercera fila, y mysqli_fetch_assoc() la lee. Comprobar el valor de retorno de mysqli_data_seek() permite manejar correctamente un desplazamiento fuera de rango.

Releer un conjunto de resultados desde el principio

Una forma habitual, sin necesidad de base de datos, de ver exactamente cómo se comporta el puntero es recorrer un resultado y luego volver a 0 para recorrerlo de nuevo. Este fragmento usa un array PHP simple para modelar la misma lógica de búsqueda sin necesitar un servidor MySQL activo:

<?php
// A result set modelled as an in-memory array of rows.
$rows = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob'],
    ['id' => 3, 'name' => 'Carol'],
];

$pointer = 0;

// "data_seek": move the pointer to an arbitrary index, like mysqli_data_seek().
function data_seek(array $rows, int $offset, int &$pointer): bool
{
    if ($offset < 0 || $offset >= count($rows)) {
        return false;
    }
    $pointer = $offset;
    return true;
}

// First pass: read every row sequentially.
echo "First pass:\n";
while ($pointer < count($rows)) {
    echo $rows[$pointer]['name'] . "\n";
    $pointer++;
}

// Rewind to the top and read again.
data_seek($rows, 0, $pointer);

echo "Second pass (after seek to 0):\n";
echo $rows[$pointer]['name'] . "\n"; // Alice again
?>

Esto imprime:

First pass:
Alice
Bob
Carol
Second pass (after seek to 0):
Alice

Con un mysqli_result real, reemplazaría la lógica del array con mysqli_data_seek($result, 0) seguido de mysqli_fetch_assoc($result) para rebobinar un resultado en búfer sin volver a ejecutar la consulta.

Cuándo usar LIMIT/OFFSET en su lugar

mysqli_data_seek() sirve para navegar por un conjunto de resultados que ya se ha descargado. Si el objetivo es obtener solo una porción de una tabla grande, no traiga todas las filas a PHP solo para hacer seek — delegue el trabajo a la base de datos con LIMIT y OFFSET:

SELECT id, name FROM users ORDER BY id LIMIT 10 OFFSET 20;

Esto devuelve solo las 10 filas que necesita, ahorrando memoria y tráfico de red. Reserve mysqli_data_seek() para los casos en que realmente necesite acceso aleatorio a través de un conjunto de resultados que ya está en memoria — por ejemplo, releer filas anteriores durante una sola solicitud.

Conclusión

mysqli_data_seek() reposiciona el puntero interno de un conjunto de resultados en búfer para que pueda saltar a cualquier fila de base cero, incluyendo el regreso al inicio. Recuerde sus dos restricciones: el desplazamiento debe estar en rango (0num_rows - 1), y el resultado debe estar en búfer. Para reducir conjuntos de datos grandes, prefiera SQL LIMIT/OFFSET; para moverse por datos que ya están en memoria, mysqli_data_seek() es la herramienta adecuada.

Funciones relacionadas: mysqli_fetch_assoc(), mysqli_fetch_array(), mysqli_fetch_row() y mysqli_query().

Práctica

Práctica
¿Cuál es la función principal del método PHP mysql_data_seek()?
¿Cuál es la función principal del método PHP mysql_data_seek()?
Was this page helpful?