W3docs

readfile()

In PHP, la funzione readfile() legge il contenuto di un file e lo invia al browser. È il metodo standard per i download di file.

Introduzione

La funzione PHP readfile() legge un file e lo scrive direttamente nel buffer di output, restituendo il numero di byte letti. Poiché trasmette il file direttamente all'output invece di conservarlo in una variabile PHP, è il metodo più efficiente in termini di memoria per inviare un file al browser — ed è esattamente per questo che rappresenta lo strumento standard per i download di file.

Questo capitolo tratta la sintassi e i parametri di readfile(), i valori restituiti, le differenze rispetto a funzioni correlate come file_get_contents() e fread(), e come utilizzarla in modo sicuro per visualizzare e scaricare file.

Sintassi

readfile(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null
): int|false
ParametroDescrizione
$filenamePercorso (o URL, se allow_url_fopen è abilitato) del file da leggere e inviare in output.
$use_include_pathSe true, PHP cerca il file anche nell'include_path. Il valore predefinito è false.
$contextUna risorsa di contesto stream opzionale (creata con stream_context_create()).

Valore restituito: il numero di byte letti, oppure false in caso di errore. Verificare sempre il valore restituito anziché ignorarlo, poiché un file mancante genera un avviso e invia comunque una risposta parziale (spesso vuota).

Come funziona readfile()

Quando si chiama readfile(), PHP apre il file, ne copia i byte nel buffer di output in blocchi e li invia al client. Il contenuto completo non viene mai caricato in una stringa PHP, quindi l'utilizzo della memoria rimane basso anche per file di diversi gigabyte. Il compromesso: non si ha la possibilità di trasformare i dati — ciò che viene inviato è una copia byte per byte del file.

readfile() vs. le alternative

Scegliere la funzione giusta è importante:

  • readfile() — trasmette un file direttamente all'output. Ideale per download e per servire file grezzi. Non restituisce una stringa, solo il conteggio dei byte inviati.
  • file_get_contents() — legge l'intero file in una stringa in modo da poterlo modificare, cercare o memorizzare. Utilizza memoria proporzionale alla dimensione del file.
  • fopen() + fread() — apre un handle per una lettura precisa basata sulla posizione; da usare quando si desidera leggere in blocchi controllati o spostarsi all'interno del file.
  • highlight_file() — invia in output un file con evidenziazione della sintassi PHP (per mostrare il codice sorgente).

Regola generale: se si vuole solo inviare il file, usare readfile(); se si vuole elaborare il file, leggerlo invece in una variabile.

Esempi

Esempio 1: Visualizzare un file di testo

<?php

readfile('example.txt');

Questo invia il contenuto di example.txt direttamente al browser. Senza un'intestazione Content-Type impostata, viene applicato il valore predefinito del server (di solito text/html).

Esempio 2: Verificare il valore restituito

readfile() restituisce il conteggio dei byte, utile per il logging o la gestione degli errori:

<?php

$bytes = readfile('example.txt');

if ($bytes === false) {
    http_response_code(404);
    echo 'File not found.';
}

Esempio 3: Forzare un download

Per fare in modo che il browser scarichi un file anziché visualizzarlo, inviare le intestazioni corrette prima di qualsiasi output, quindi chiamare readfile():

<?php

$file = 'report.pdf';

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));

readfile($file);
exit;
  • Content-Type: application/octet-stream indica al browser che si tratta di un download binario.
  • Content-Disposition: attachment; filename="..." attiva la finestra di dialogo "Salva con nome" e imposta il nome suggerito.
  • Content-Length consente al browser di mostrare una barra di avanzamento accurata.

Le intestazioni provengono dalla funzione header() e devono essere inviate prima che la funzione produca qualsiasi byte — altrimenti si ottiene un errore "headers already sent".

Errori comuni

  • Non passare mai input utente non sanificato come $filename. Un valore come ../../etc/passwd permetterebbe a un attaccante di leggere file arbitrari (un attacco di path traversal). Limitare i file consentiti tramite whitelist oppure elaborare il percorso con basename() e confinarlo in una directory conosciuta.
  • Nessun output prima delle intestazioni. Anche uno spazio o un BOM prima di <?php viene considerato output e interrompe Content-Disposition.
  • Svuotare il buffer di output per file di grandi dimensioni. Se il buffer di output è abilitato, il file può ancora essere memorizzato in memoria. Chiamare ob_end_clean() (o flush()) prima di readfile() quando si trasmettono file molto grandi.
  • La lettura di URL remoti richiede che allow_url_fopen sia abilitato in php.ini.

Conclusione

readfile() è la funzione di riferimento in PHP per inviare un file al client con il minimo overhead di memoria: trasmette i byte direttamente all'output e restituisce il numero di byte inviati. Usarla per i download e per servire file grezzi, abbinarla a header() per i download, validare il nome del file per evitare attacchi di path traversal, e ricorrere a file_get_contents() quando si ha effettivamente bisogno del contenuto del file in una variabile.

Esercitazione

Pratica
Cosa fa la funzione PHP readfile()?
Cosa fa la funzione PHP readfile()?
Was this page helpful?