W3docs

data_seek

Scopri come usare mysqli_data_seek() in PHP per spostare il puntatore del risultato a una riga specifica in un result set bufferizzato.

La funzione mysqli_data_seek() in PHP sposta il puntatore interno del risultato a una riga arbitraria in un result set bufferizzato, così la successiva chiamata di fetch leggerà da quella riga anziché dalla successiva in sequenza. Permette di saltare direttamente a una riga, rileggere righe già passate o ricominciare dall'inizio senza eseguire nuovamente la query. Gli indici di riga sono a base zero e la funzione restituisce true in caso di successo o false in caso di errore.

Questo capitolo tratta la firma della funzione, gli stili procedurale e orientato agli oggetti, un esempio eseguibile, il requisito del result set bufferizzato che crea problemi alla maggior parte delle persone, e quando SQL LIMIT … OFFSET è lo strumento migliore.

Sintassi

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

// Object-oriented style
$result->data_seek(int $offset): bool
  • $result — un result set restituito da mysqli_query(), mysqli_store_result() o mysqli_use_result().
  • $offset — il numero di riga su cui spostarsi, a partire da 0 per la prima riga. Deve essere compreso tra 0 e mysqli_num_rows() - 1.
  • Valore restituitotrue se lo spostamento ha successo, false se l'offset è fuori intervallo o il result set non è bufferizzato.

Il requisito del result set bufferizzato

mysqli_data_seek() funziona solo con result set bufferizzati — quelli le cui righe sono già tenute in memoria. Questo è ciò che si ottiene da mysqli_query() (che chiama mysqli_store_result() internamente) e da mysqli_store_result() direttamente.

Se si recuperano le righe in modo pigro con mysqli_use_result(), le righe vengono trasmesse dal server una alla volta e non c'è nulla su cui eseguire lo spostamento, quindi mysqli_data_seek() fallirà. Quando si necessita di accesso casuale, è necessario utilizzare un result set bufferizzato.

Come usare mysqli_data_seek()

Chiama la funzione su un result set valido e passa l'indice di riga su cui vuoi posizionarti. Il fetch successivo restituirà quella riga:

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

Ci connettiamo con mysqli_connect(), eseguiamo la query con mysqli_query() e controlliamo gli errori. Poi mysqli_data_seek($result, 2) sposta il puntatore alla terza riga, e mysqli_fetch_assoc() la legge. Controllare il valore restituito da mysqli_data_seek() consente di gestire in modo pulito un offset fuori intervallo.

Rileggere un result set dall'inizio

Un modo comune, senza database, per vedere esattamente come si comporta il puntatore è scorrere un result set, poi tornare a 0 e scorrere di nuovo. Questo frammento usa un semplice array PHP per simulare la stessa logica di fetch-poi-seek senza la necessità di un server MySQL attivo:

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

Questo stampa:

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

Con un vero mysqli_result, si sostituirebbe la logica dell'array con mysqli_data_seek($result, 0) seguito da mysqli_fetch_assoc($result) per riavvolgere un result set bufferizzato senza rieseguire la query.

Quando usare LIMIT/OFFSET invece

mysqli_data_seek() serve a navigare in un result set che si è già scaricato. Se l'obiettivo è recuperare solo una porzione di una tabella grande, non portare tutte le righe in PHP solo per fare uno spostamento — delega il lavoro al database con LIMIT e OFFSET:

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

Questo restituisce solo le 10 righe desiderate, risparmiando memoria e traffico di rete. Riserva mysqli_data_seek() per i casi in cui hai genuinamente bisogno di accesso casuale su un result set già in memoria — ad esempio, rileggere righe precedenti durante una singola richiesta.

Conclusione

mysqli_data_seek() riposiziona il puntatore interno di un result set bufferizzato in modo da poter saltare a qualsiasi riga a base zero, compreso il ritorno all'inizio. Ricorda i suoi due vincoli: l'offset deve essere nell'intervallo (0num_rows - 1) e il result set deve essere bufferizzato. Per ridurre dataset di grandi dimensioni, preferisci SQL LIMIT/OFFSET; per spostarti tra dati già in memoria, mysqli_data_seek() è lo strumento giusto.

Funzioni correlate: mysqli_fetch_assoc(), mysqli_fetch_array(), mysqli_fetch_row() e mysqli_query().

Esercitazione

Pratica
Qual è la funzione principale del metodo PHP mysql_data_seek()?
Qual è la funzione principale del metodo PHP mysql_data_seek()?
Was this page helpful?