rewind()
Scopri come usare la funzione rewind() in PHP per resettare il puntatore di file all'inizio, con sintassi, esempi e insidie comuni.
Introduzione
Quando leggi un file in PHP, un puntatore di file interno tiene traccia della posizione corrente. Ogni lettura avanza il puntatore, quindi una volta raggiunta la fine del file, le letture successive non restituiscono nulla. La funzione rewind() sposta il puntatore al byte 0 — proprio all'inizio — permettendo di leggere lo stesso file di nuovo senza chiuderlo e riaprirlo.
Questa pagina spiega cosa fa rewind(), la sua sintassi e il valore restituito, quando usarla, le insidie comuni e degli esempi eseguibili che puoi adattare.
Cos'è il puntatore di file
Pensa al puntatore di file come a un cursore all'interno del file aperto. Funzioni come fread(), fgets() e fgetcsv() leggono da quel cursore e lo avanzano del numero di byte consumati. Puoi ispezionare il cursore con ftell() e spostarlo in una posizione arbitraria con fseek().
rewind($handle) è la comoda scorciatoia per "torna all'inizio" — equivale a fseek($handle, 0).
Sintassi
rewind(resource $handle): bool$handle— una risorsa puntatore di file ancora aperta, tipicamente restituita dafopen(). Deve puntare a uno stream riposizionabile.- Restituisce
truein caso di successo efalsein caso di errore.
Perché e quando usarla
Usa rewind() ogni volta che hai bisogno di leggere o elaborare lo stesso file aperto più di una volta durante l'esecuzione di uno script:
- Contare e poi elaborare. Prima passata per contare le righe o validare, seconda passata per il lavoro vero e proprio.
- Rilettura dopo la scrittura. Dopo aver scritto in un file aperto in modalità lettura/scrittura (
'w+','r+','a+'), fai il rewind prima di rileggere ciò che hai scritto. - Stream in memoria. Quando costruisci contenuto in uno stream
php://memoryophp://temp, fai il rewind prima di leggerlo.
Se leggi un file una sola volta, non hai affatto bisogno di rewind().
Esempi
Esempio 1: Leggere lo stesso file due volte
Questo esempio crea un file temporaneo, lo legge fino in fondo, poi fa il rewind e lo legge di nuovo.
<?php
// Create a temporary file we can read and write.
$handle = tmpfile();
fwrite($handle, "line one\nline two\n");
// Move to the start so we can read what we just wrote.
rewind($handle);
echo "First read:\n";
echo fread($handle, 1024);
// The pointer is now at the end; reading again gives nothing.
echo "After first read, position: " . ftell($handle) . "\n";
// Rewind and read the whole file again.
rewind($handle);
echo "Second read:\n";
echo fread($handle, 1024);
fclose($handle);Output:
First read:
line one
line two
After first read, position: 18
Second read:
line one
line twoIl primo fread() lascia il puntatore al byte 18 (la fine del file). Senza rewind(), una seconda lettura restituirebbe una stringa vuota. Dopo il rewind, il puntatore torna a 0 e il contenuto completo è nuovamente disponibile.
Esempio 2: Scrivere, fare il rewind e rileggere
Quando uno stream è aperto sia in scrittura che in lettura, rewind() permette di verificare ciò che hai scritto.
<?php
// php://memory is an in-memory read/write stream.
$handle = fopen('php://memory', 'r+');
fwrite($handle, 'Hello, W3Docs!');
// Without rewind, the pointer sits after the written text,
// so reading now would return an empty string.
rewind($handle);
$content = stream_get_contents($handle);
echo $content; // Hello, W3Docs!
fclose($handle);Output:
Hello, W3Docs!Esempio 3: Controllare sempre il valore restituito
rewind() restituisce false quando lo stream non può essere riposizionato (ad esempio, uno stream di rete o pipe non seekable).
<?php
$handle = fopen('php://memory', 'r+');
fwrite($handle, 'data');
if (rewind($handle)) {
echo "Pointer reset. Position: " . ftell($handle) . "\n";
} else {
echo "This stream cannot be rewound.\n";
}
fclose($handle);Output:
Pointer reset. Position: 0Insidie comuni
- Il puntatore è già alla fine dopo la lettura. Questo è il motivo per cui esiste
rewind(). Se una seconda lettura non restituisce nulla, probabilmente hai dimenticato di fare il rewind. - Modalità append (
'a'/'a+'). Il rewind sposta il puntatore di lettura all'inizio, ma in modalità append ognifwrite()aggiunge comunque alla fine del file indipendentemente dalla posizione del puntatore. - Stream non seekable. Pipe, socket e alcuni stream HTTP non possono essere riavvolti;
rewind()restituiscefalse. Controlla il valore restituito quando la sorgente potrebbe non essere seekable. - Handle chiusi. Chiamare
rewind()su un handle già passato afclose()genera un avviso. Fai il rewind prima di chiudere.
Funzioni correlate
fseek()— sposta il puntatore a qualsiasi offset in byte (rewind()equivale afseek($handle, 0)).ftell()— riporta la posizione corrente del puntatore.fopen()— apre un file o uno stream e restituisce l'handle.fread()/fgets()— legge dalla posizione corrente.fclose()— chiude l'handle quando hai finito.
Conclusione
rewind() reimposta il puntatore interno di un file aperto all'inizio, così puoi rileggere o rielaborare i dati nella stessa esecuzione dello script. È un comodo wrapper sottile attorno a fseek($handle, 0). Ricorda di controllare il valore restituito per gli stream non seekable, tieni a mente il comportamento della modalità append e fai il rewind prima di chiudere l'handle.