data_seek
Aprenda sobre a função mysqli_data_seek() no PHP, usada para mover o ponteiro de resultado para uma linha específica em um conjunto de resultados.
A função mysqli_data_seek() no PHP move o ponteiro interno de resultado para uma linha arbitrária em um conjunto de resultados armazenado em buffer, de modo que a próxima chamada de busca leia a partir dessa linha em vez da próxima sequencial. Ela permite que você salte diretamente para uma linha, releia linhas que já passou ou reinicie do início sem executar a consulta novamente. Os índices de linha são baseados em zero, e a função retorna true em caso de sucesso ou false em caso de falha.
Este capítulo aborda a assinatura da função, os estilos procedural e orientado a objetos, um exemplo executável, o requisito de resultado armazenado em buffer que confunde a maioria das pessoas, e quando SQL LIMIT … OFFSET é a ferramenta mais adequada.
Sintaxe
// Procedural style
mysqli_data_seek(mysqli_result $result, int $offset): bool
// Object-oriented style
$result->data_seek(int $offset): bool$result— um conjunto de resultados retornado pormysqli_query(),mysqli_store_result()oumysqli_use_result().$offset— o número da linha para a qual mover, começando em0para a primeira linha. Deve estar entre0emysqli_num_rows() - 1.- Valor de retorno —
truese a operação for bem-sucedida,falsese o deslocamento estiver fora do intervalo ou o conjunto de resultados não estiver armazenado em buffer.
O requisito de resultado armazenado em buffer
mysqli_data_seek() funciona apenas em conjuntos de resultados armazenados em buffer — aqueles cujas linhas já estão na memória. É isso que você obtém com mysqli_query() (que chama mysqli_store_result() internamente) e com mysqli_store_result() diretamente.
Se você buscar linhas de forma lazy com mysqli_use_result(), as linhas são transmitidas do servidor uma de cada vez e não há nada para percorrer, portanto mysqli_data_seek() falhará. Quando precisar de acesso aleatório, use um resultado armazenado em buffer.
Como usar mysqli_data_seek()
Chame a função em um conjunto de resultados válido e passe o índice da linha para a qual deseja ir. A próxima busca retornará essa linha:
<?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);
?>Conectamos com mysqli_connect(), executamos a consulta com mysqli_query() e verificamos erros. Em seguida, mysqli_data_seek($result, 2) move o ponteiro para a terceira linha, e mysqli_fetch_assoc() a lê. Verificar o valor de retorno de mysqli_data_seek() permite que você trate um deslocamento fora do intervalo de forma adequada.
Relendo um conjunto de resultados do início
Uma maneira comum, sem banco de dados, de ver exatamente como o ponteiro se comporta é percorrer um resultado, depois retornar ao 0 e percorrê-lo novamente. Este trecho usa um array PHP simples para modelar a mesma lógica de busca-e-retorno sem precisar de um servidor MySQL ativo:
<?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
?>Isso imprime:
First pass:
Alice
Bob
Carol
Second pass (after seek to 0):
AliceCom um mysqli_result real, você substituiria a lógica de array por mysqli_data_seek($result, 0) seguido de mysqli_fetch_assoc($result) para retroceder um resultado armazenado em buffer sem executar a consulta novamente.
Quando usar LIMIT/OFFSET em vez disso
mysqli_data_seek() serve para navegar em um conjunto de resultados que você já baixou. Se seu objetivo é buscar apenas uma fatia de uma tabela grande, não traga todas as linhas para o PHP apenas para percorrê-las — delegue o trabalho ao banco de dados com LIMIT e OFFSET:
SELECT id, name FROM users ORDER BY id LIMIT 10 OFFSET 20;Isso retorna apenas as 10 linhas desejadas, economizando memória e tráfego de rede. Reserve mysqli_data_seek() para casos em que você genuinamente precisa de acesso aleatório em um conjunto de resultados que já está na memória — por exemplo, relendo linhas anteriores durante uma única requisição.
Conclusão
mysqli_data_seek() reposiciona o ponteiro interno de um conjunto de resultados armazenado em buffer para que você possa saltar para qualquer linha baseada em zero, inclusive de volta ao início. Lembre-se de suas duas restrições: o deslocamento deve estar dentro do intervalo (0 … num_rows - 1), e o resultado deve estar armazenado em buffer. Para reduzir grandes conjuntos de dados, prefira SQL LIMIT/OFFSET; para mover-se por dados já na memória, mysqli_data_seek() é a ferramenta certa.
Funções relacionadas: mysqli_fetch_assoc(), mysqli_fetch_array(), mysqli_fetch_row() e mysqli_query().