PHP - Scarica File

Ciao a tutti, futuri sviluppatori PHP! Oggi andremo a esplorare un argomento entusiasmante che ti permetterà di aggiungere alcune funzionalità interessanti ai tuoi siti web - scaricare file utilizzando PHP. Come il tuo insegnante di computer del vicinato, sono qui per guidarti in questo viaggio passo dopo passo. Allora, prenditi la tua bevanda preferita, mettiti comodo e iniziamo a programmare!

PHP - Download File

La Funzione readfile()

Al cuore dello scaricamento dei file in PHP c'è la funzione readfile(). Questa piccola funzione è lo strumento ideale quando vuoi leggere un file e scrivere il suo contenuto nel buffer di output. Ora, non preoccuparti se questo sembra un po' tecnico - lo spiegheremo insieme!

Uso di Base

Iniziamo con un esempio semplice:

<?php
readfile("example.txt");
?>

In questo frammento di codice, readfile() legge il contenuto di "example.txt" e lo outputta direttamente nel browser. È come magia - il contenuto del file appare sullo schermo!

Scaricare File

Ora, è qui che diventa interessante. Possiamo usare readfile() per avviare uno scaricamento. Guardiamo un esempio più completo:

<?php
$file = "myfile.pdf";

if(file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>

Wow, c'è molto da digerire! Analizziamo:

  1. Specificiamo il file che vogliamo scaricare ($file = "myfile.pdf").
  2. Controlliamo se il file esiste utilizzando file_exists().
  3. Se esiste, impostiamo una serie di intestazioni:
  • Content-Description dice al browser che si tratta di un trasferimento di file.
  • Content-Type imposta il tipo MIME a un file binario generico.
  • Content-Disposition avvia il download del file.
  • Le altre intestazioni assicurano che il file non venga memorizzato nella cache e venga gestito correttamente.
  1. Infine, usiamo readfile() per outputtare il contenuto del file.

Tipi di File Comuni

I diversi tipi di file possono richiedere diverse intestazioni. Ecco una tabella utile dei tipi di file comuni e le loro intestazioni Content-Type:

Tipo di File Intestazione Content-Type
PDF application/pdf
ZIP application/zip
JPEG image/jpeg
PNG image/png
MP3 audio/mpeg
MP4 video/mp4

Creare un Link di Download

Ora che sappiamo come avviare uno scaricamento, creiamo un link di download user-friendly:

<!DOCTYPE html>
<html>
<body>

<h2>Scarica File</h2>
<p><a href="download.php?file=myfile.pdf">Scarica PDF</a></p>

</body>
</html>

In questo HTML, creiamo un link a uno script PHP (download.php) che gestirà lo scaricamento del file. Passiamo il nome del file come parametro nell'URL.

Ora, creiamo lo script download.php:

<?php
if(isset($_GET['file'])) {
$file = $_GET['file'];
$filepath = "uploads/" . $file;

if(file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit;
} else {
echo "File non trovato.";
}
}
?>

Questo script fa quanto segue:

  1. Controlla se è stato passato un parametro file nell'URL.
  2. Costruisce il percorso completo del file (assumendo che i file siano in una directory "uploads").
  3. Se il file esiste, imposta le intestazioni e avvia il download.
  4. Se il file non esiste, visualizza un messaggio di errore.

Considerazioni di Sicurezza

Ora, so cosa stai pensando - "Ma maestro, non è un po' rischioso? E se qualcuno cercasse di scaricare file che non dovrebbero?" Ottima domanda! Hai assolutamente ragione, ed è per questo che dobbiamo parlare di sicurezza.

Validazione dei Percorsi dei File

Non dovremmo mai fidarci dell'input dell'utente direttamente. Ecco una versione migliorata del nostro script di download:

<?php
if(isset($_GET['file'])) {
$file = basename($_GET['file']);
$filepath = "uploads/" . $file;

// Validazione del percorso del file
$realPath = realpath($filepath);
$uploadDir = realpath("uploads/");

if($realPath === false || strpos($realPath, $uploadDir) !== 0) {
die("Percorso del file non valido.");
}

if(file_exists($filepath)) {
// ... (resto del codice di download)
} else {
echo "File non trovato.";
}
}
?>

In questa versione:

  1. Usiamo basename() per rimuovere eventuali tentativi di traversal della directory.
  2. Usiamo realpath() per ottenere il percorso reale del file e della directory degli upload.
  3. Controlliamo se il percorso reale del file inizia con il percorso della directory degli upload, assicurandoci di non accedere a file al di fuori della directory prevista.

Conclusione

Eccoci, ragazzi! Abbiamo intrapreso un viaggio attraverso il territorio degli scaricamenti di file PHP, dai fondamentali di readfile() alla creazione di link di download e abbiamo toccato anche alcune importanti considerazioni di sicurezza. Ricorda, con grande potere arriva grande responsabilità - sempre validare l'input dell'utente e pensa alla sicurezza quando lavoro con scaricamenti di file.

Spero che questa lezione ti sia piaciuta quanto me è piaciuto insegnarla. Continua a esercitarti, a programmare, e prima di sapere, sarai creare applicazioni PHP straordinarie con tutte le sorti di funzionalità di download. Fino alla prossima volta, happy coding!

Credits: Image by storyset