30 Sep 2011 11 commenti
Fornire agli utenti la possibilità di scaricare file attraverso il nostro sito web è un'operazione nel complesso semplice ma che richiede particolari accorgimenti.
Il modo più semplice per fare ciò prevede un normale tag <a> html con l'attributo href indicante il percorso al file.
<a href="file.zip" target="_blank">Scarica il file</a>
Questa tecnica è perfettamente funzionale per molte tipologie di file archivio: .zip, .tar, .gzip.
Al contrario, il comportamento predefinito dei browser per molte altre tipologie di file (ad esempio .pdf, .mp3, .doc) prevedono l'apertura di una nuova finestra.
Tale comportamento è possibile modificarlo inviando al browser gli opportuni headers così da far aprire la finestra del "Salva con nome" e consentire all'utente di salvarlo immediatamente sul proprio pc. In particolare l'headers in oggetto sarà:
Content-disposition: attachment;
Per inviare tale headers al browser possiamo impiegare due tecniche:
- la prima farà ricorso ad un file .htaccess;
- con la seconda, invece, il download del file e l'invio degli headers avverrà in modo indiretto tramite uno script php.
Forzare il download tramite .htaccess
In questo caso è utile collocare i file per il downaload in una cartella dedicata e al suo internoandremo a creare un file .htaccess con le seguenti istruzioni:
<FilesMatch "\.(?i:doc|xls|pdf|mp3|txt)"> ForceType application/octet-stream Header set Content-Disposition attachment </FilesMatch>
Così come impostato gli headers verranno modificati per i file con estensione doc, xls, pdf, mp3 e txt (ovviamente potete modificarlo a vostro piacimento eliminando i presenti o inserendone di nuovi).
A questo punto il semplice link come quello precedentemente descirtto (il tag <a>) ad uno di essi farà aprire la finestra del download secondo le specifiche dei vari browser.
Impostare gli header per il download con Php
Con la seconda tecnica il download del file avverrà attraverso un file php che farà da "filtro".
Ecco di seguito un codice di esempio di un file che chiameremo, ad esempio download.php:
<?php /* impostiamo la cartella in cui sono presenti i file per il download */ $dir = "download/"; /* riceviamo via GET il file da scaricare la funzione basename la applichiamo al fine di evitare che utenti maliziosi possano eseguire percorsi nell'URL */ $file = isset($_GET['file']) ? basename( (string) $_GET['file'] ) : ''; $path = $dir . $file; /* eseguiamo alcuni controlli preventivi */ if($file==''){ exit('Nessun file indicato'); } else if(!is_file($path)){ exit('Il file non esiste'); } else if(!is_readable($path)){ exit('Il file non ha i permessi per essere scaricato'); } /* otteniamo alcune info sul file */ $info = pathinfo( $path ); $extension = $info['extension']; // estensione $size = filesize($path); // dimensione in byte $time_file = date( 'r', filemtime( $path ) ); // time ultima modifica /* inviamo gli opportuni headers */ /* alcuni di questi sono degli hack (trucchi) per farlo funzionare correttamente anche su alcune versioni di IE*/ header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'. basename($path) .'"'); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . $size); header('Last-Modified: ' . $time_file); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); /* eliminiamo eventuale output inviato */ ob_clean(); flush(); /* leggiamo il file inviamo l'output */ @readfile($path) or die('SERVER ERROR!'); exit; ?>
A questo punto per consentire il download del file "document.pdf" faremo un link al file download.php indereno nella quesry string la variabile get "file", ovvero:
<a href="download.php?file=document.pdf" target="_blank">SCARICA IL FILE</a>
La classe ForceDownload
Essendo questa un operazione che integro spesso nei miei siti ho creato la classe ForceDownload la quale segue il medesimo approccio ma con la comodità di snellire tutta la procedura.
Ecco di seguito il link per il download della classe.
Il suo utilizzo è molto semplice. Il file download.php sarà molto più sinteticamente il seguente:
<?php require_once('ForceDownload.class.php'); $dir = "download/"; $file = isset($_GET['file']) ? $_GET['file'] : ''; $download = New ForceDownload($dir, $file); $download->download() or die ($download->get_error());
Come in precedenza basterà un link al file downalod con indicazione nella query string nella variabile get "file" del nome del file.
Conclusioni
Le due tecniche sono descritte come alternative ma alle volte l'una è da preferire all'altra. Personalmente preferisco adottare quella con php dato.
Se hai avuto problemi nell'implementare tale funzionalità lasciami pure un commento. Se invece ti sono stato di aiuto condividi questo articolo sui social e iscriviti alla mia fan page così da essere aggiornato sui prossimi articoli.
Olimpio Romanella
Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.
Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.
11 Commenti presenti
Ciao Olimpio,
sto provando e riprovando lo script per il download di file, ma viene sempre visualizzata la finestra di dialogo.
Ho eseguito l'esempio che ho scaricato dal tuo sito, ma mi chiede sempre se voglio aprirlo oppure salvarlo.
Io vorrei che il download dei file contenuti all'interno della cartella venisse eseguito senza l'apertura della finestra di salvataggio.
Grazie, dopo tante ore mi hai risolto un problema non da poco
Adriana
15 May 2020 ore 09:57
Buongiorno
Avrei bisogno di scaricare dei file su whatsapp ma non riesco più ad effettuare il download, potete aiutarmi ?