fgets()
La funzione fgets() in PHP legge una riga alla volta da un file aperto e la restituisce come string.
La funzione fgets() legge una riga alla volta da un handle di file aperto. È il metodo standard per elaborare file di testo in PHP senza caricare l'intero file in memoria — il che è importante quando un file è abbastanza grande da rendere la lettura completa (con file_get_contents() o fread()) dispendiosa o impossibile.
Questa pagina tratta la sintassi, cosa restituisce fgets(), il ciclo di lettura corretto, gli errori comuni e come si relaziona con le altre funzioni di lettura di file.
Cos'è la funzione fgets()?
fgets() legge dalla posizione corrente di un handle di file aperto fino a includere il successivo carattere di a capo (\n), e restituisce quel testo come string. Poi avanza il puntatore al file in modo che la chiamata successiva legga la riga seguente.
Non è limitata ai file su disco: qualsiasi stream aperto con fopen() funziona, incluso php://stdin per leggere l'input da tastiera e URL remoti.
Sintassi
fgets(resource $stream, ?int $length = null): string|false$stream— un puntatore a file restituito dafopen()(o da un'altra funzione stream). Deve essere ancora aperto.$length(opzionale) — legge al massimo$length - 1byte. La lettura si interrompe quando viene raggiunto un a capo, la fine del file, oppure sono stati letti$length - 1byte, a seconda di quale condizione si verifica per prima. Omettilo per leggere fino alla fine della riga indipendentemente dalla sua lunghezza.
Cosa restituisce fgets()
| Situazione | Valore restituito |
|---|---|
| È stata letta una riga | La riga come string, con il \n finale incluso |
| Fine del file già raggiunta | false |
| Si è verificato un errore | false |
Poiché il carattere di a capo viene mantenuto, echo riproduce le interruzioni di riga del file. Se non le vuoi, eliminale con rtrim($line, "\r\n").
Il fatto che
fgets()restituiscafalsealla fine del file è ciò che fa funzionare il ciclo di lettura qui sotto — non hai nemmeno bisogno difeof().
Come usare fgets(): i tre passaggi
- Apri il file con
fopen()in una modalità di lettura come"r". - Leggi riga per riga con
fgets(). - Chiudi l'handle con
fclose()quando hai finito.
Il ciclo di lettura consigliato
Il pattern più pulito usa il valore di ritorno false come condizione del ciclo. L'assegnazione in PHP restituisce il valore assegnato, quindi while (($line = fgets($file)) !== false) legge una riga e la testa in un solo passaggio:
<?php
$file = fopen("file.txt", "r");
if ($file === false) {
exit("Could not open the file.\n");
}
while (($line = fgets($file)) !== false) {
echo $line; // newline is already part of $line
}
fclose($file);Il confronto stretto !== false è importante: una riga contenente solo "0" è "falsy" in PHP, quindi un semplice while ($line = fgets($file)) si interromperebbe prematuramente su quella riga. Confronta sempre con !== false.
Lettura riga per riga con feof()
Vedrai anche il ciclo scritto con feof(), che restituisce true una volta raggiunta la fine del file:
<?php
$file = fopen("file.txt", "r");
while (!feof($file)) {
$line = fgets($file);
if ($line === false) {
break; // guard against a read failure mid-loop
}
echo $line;
}
fclose($file);Entrambi gli stili sono corretti. La versione con !== false è generalmente preferita perché feof() diventa true solo dopo che una lettura è fallita, il che può causare un'iterazione vuota in più se non si fa attenzione.
Limitare la lunghezza della riga
Passa $length per limitare quanti byte di una riga lunga leggere alla volta. Qui vengono restituiti solo i primi 9 byte ($length - 1) di ogni blocco:
<?php
$file = fopen("file.txt", "r");
// "Hello, world!" is read in pieces of at most 9 bytes
echo fgets($file, 10); // "Hello, wo"
echo "\n";
echo fgets($file, 10); // "rld!" (rest of the line)
fclose($file);Questo è utile per proteggersi da righe patologicamente lunghe, ma per i normali file di testo puoi omettere $length.
Lettura dell'input utente dal terminale
Poiché fgets() funziona su qualsiasi stream, è il modo classico per leggere una riga digitata dall'utente sulla riga di comando:
<?php
echo "What is your name? ";
$name = rtrim(fgets(STDIN), "\r\n"); // strip the Enter key's newline
echo "Hello, $name!\n";STDIN è una costante predefinita per php://stdin.
Errori comuni
- Il carattere di a capo finale è incluso. Usa
rtrim($line, "\r\n")quando confronti o salvi valori. - Testa con
!== false, non solo con la veridicità, in modo che righe come"0"o""non interrompano il ciclo prematuramente. fgets()richiede un handle valido e aperto. Sefopen()ha restituitofalse(file mancante, permessi errati), passarlo afgets()genera un avviso. Controlla prima l'handle.- Non dimenticare
fclose(). PHP chiude gli handle alla fine dello script, ma liberarli esplicitamente è una buona pratica, soprattutto negli script a lunga esecuzione. - Per leggere file interi, preferisci strumenti più semplici. Se non hai bisogno del controllo riga per riga,
file()restituisce il file come array di righe efile_get_contents()lo restituisce come una string unica.
Funzioni correlate
fopen()— apre un file o stream (necessario prima difgets()).fread()— legge un numero fisso di byte, non righe.fgetc()— legge un singolo carattere.fgetcsv()— legge una riga e la interpreta come CSV.feof()— verifica la fine del file.fclose()— chiude l'handle.
Conclusione
fgets() legge un file una riga alla volta, restituendo ogni riga (a capo incluso) fino alla fine del file, dove restituisce false. Usala insieme a fopen() e fclose(), gestisci il ciclo con un test rigoroso !== false, e ricorda di usare rtrim() sull'a capo quando hai bisogno del valore pulito. Per file molto grandi questo mantiene l'uso della memoria costante, rendendo fgets() la scelta ideale per lo streaming di testo in PHP.