W3docs

fpassthru()

La funzione fpassthru() di PHP legge i dati rimanenti da un puntatore a file aperto e li invia direttamente allo stream di output.

Che cos'è la funzione fpassthru()?

La funzione fpassthru() è una funzione PHP integrata che legge tutti i dati rimanenti da un puntatore a file aperto — partendo dalla posizione corrente del puntatore e continuando fino alla fine del file (EOF) — e li scrive direttamente nello stream di output (ciò che il browser o il terminale riceve). Poiché invia i dati a blocchi invece di caricare l'intero file in una stringa, è particolarmente adatta per inviare file di grandi dimensioni senza esaurire il limite di memoria di PHP.

Questa pagina illustra la sintassi della funzione, un modello di utilizzo passo dopo passo, un esempio reale di download di file, le differenze rispetto a readfile() e gli aspetti critici da conoscere.

Restituisce il numero di byte scritti nell'output in caso di successo, oppure false in caso di errore.

Ecco la sintassi di base della funzione fpassthru():

La sintassi PHP di fpassthru()

fpassthru(resource $stream): int|false

Dove $stream è un puntatore a file che deve essere valido e già aperto (tipicamente il valore restituito da fopen()). Dopo che fpassthru() ritorna, il puntatore si trova all'EOF e i dati sono stati consumati — non è possibile leggerli di nuovo senza riavvolgere il puntatore.

Come usare la funzione fpassthru()?

L'utilizzo della funzione fpassthru() è semplice. Ecco i passaggi da seguire:

  1. Aprire il file con fopen() e verificare che il puntatore si trovi nella posizione di inizio desiderata.
  2. Chiamare fpassthru() con il puntatore al file. Leggerà fino all'EOF e scriverà nello stream di output.
  3. Controllare il valore restituito per confermare il successo, quindi chiudere il file con fclose().

Ecco un esempio di codice che dimostra come utilizzare la funzione fpassthru():

Come usare la funzione fpassthru()?

<?php

$filename = 'largefile.txt';
$file = fopen($filename, 'r');
if ($file) {
   if (fpassthru($file) === false) {
      echo "Error reading file!";
   }
   fclose($file);
} else {
   echo "Unable to open file!";
}

In questo esempio, apriamo il file largefile.txt usando la funzione fopen() in modalità di sola lettura. Verifichiamo se il file è stato aperto con successo tramite un'istruzione if, e in caso affermativo ne inviamo il contenuto allo stream di output standard con fpassthru(). Verifichiamo il valore restituito per gestire eventuali errori di lettura, quindi chiudiamo l'handle con fclose().

Nota sull'output buffering: se il buffering dell'output PHP è attivo (ad esempio tramite ob_start()), fpassthru() scriverà direttamente nel buffer di output corrente invece di inviare i dati immediatamente al browser.

Lettura dalla posizione corrente, non dall'intero file

Un dettaglio fondamentale è che fpassthru() inizia dalla posizione corrente del puntatore. Se hai già letto una parte del file (ad esempio con fgets() o fread()), verranno inviati solo i byte rimanenti. Questo ti consente di leggere manualmente un'intestazione e trasmettere il resto in streaming:

<?php

$file = fopen('php://temp', 'r+');
fwrite($file, "HEADER\nbody-line-1\nbody-line-2\n");
rewind($file);

// Consume the first line manually.
echo "First line: " . fgets($file);

// Stream everything left after the pointer.
fpassthru($file);
fclose($file);

Questo stampa:

First line: HEADER
body-line-1
body-line-2

La riga HEADER non viene ripetuta, perché il puntatore era già avanzato oltre di essa quando fpassthru() è stato eseguito.

Inviare un file come download

L'uso più comune in produzione di fpassthru() è lo streaming di un file verso il browser come download. Imposta le intestazioni appropriate, apri il file in modalità binaria ('rb'), e lascia che fpassthru() invii i byte:

<?php

$path = '/var/www/files/report.pdf';

if (is_readable($path)) {
   header('Content-Type: application/pdf');
   header('Content-Disposition: attachment; filename="report.pdf"');
   header('Content-Length: ' . filesize($path));

   $file = fopen($path, 'rb');
   fpassthru($file);
   fclose($file);
   exit;
}

http_response_code(404);
echo 'File not found.';

La modalità 'rb' è importante su Windows, dove la modalità testo predefinita potrebbe corrompere dati binari come immagini, PDF o archivi. Su Linux e macOS il flag b è inoffensivo, quindi è buona pratica includerlo sempre per i download.

fpassthru() vs. readfile()

Entrambe le funzioni inviano un file in streaming verso l'output, ma operano a livelli diversi:

fpassthru($stream)readfile($path)
InputUn puntatore a file già apertoUn percorso di file (aperto internamente)
Punto di partenzaLa posizione corrente del puntatoreSempre l'inizio del file
Migliore quandoDevi leggere prima una parte del file, o hai già un handle apertoVuoi semplicemente scaricare un intero file con una sola chiamata

Se vuoi semplicemente restituire un intero file in output e non hai un handle aperto, readfile() è più concisa. Usa fpassthru() quando hai già un puntatore a file o devi saltare una porzione dello stream prima.

Conclusione

La funzione fpassthru() è uno strumento utile in PHP per leggere file di grandi dimensioni senza caricarli in memoria. Seguendo i passaggi descritti in questa guida, puoi utilizzare facilmente la funzione fpassthru() nei tuoi progetti PHP per leggere il contenuto dei file dalla posizione corrente del puntatore e inviarlo allo stream di output standard.

Pratica

Pratica
Qual è lo scopo della funzione fpassthru() in PHP?
Qual è lo scopo della funzione fpassthru() in PHP?
Was this page helpful?