Effettuare il download di un file con PHP

4
Effettuare il download di un file con PHP Download mediante link diretto Volendo consentire ad un utente del nostro sito di effettuare il download di un file, la prima cosa che viene in mente è di fornire un link diretto. Occorre fare attenzione, però, al fatto che: i file html, pdf e immagine vengono aperti direttamente nel browser ed è possibile salvarli con “Salva con nome”; i file php vengono processati dal server e non è possibile scaricarli; per tutti gli altri file, il browser chiede di salvare, se non c'è un programma associato in grado di aprirli. Esempio Supponiamo che in una cartella download del web server siano presenti i file: - esempio.html - esempio.jpg - esempio.pdf - esempio.doc Consideriamo la pagina html seguente: Il cui codice è: down.html <!doctype html> <html> <head> <meta charset="UTF-8"> <title>Download</title> </head> <body> <p>Clicca sul collegamento per scaricare i file</p> <a href="esempio.html">esempio.html</a><br> <a href="esempio.jpg">esempio.jpg</a><br> <a href="esempio.pdf">esempio.pdf</a><br> <a href="esempio.doc">esempio.doc</a> </body> </html> Se si desidera, invece, forzare il download, indipendentemente dal tipo di file, occorre agire in modo diverso, intervenendo sugli header http. Prima di proseguire, vediamo sinteticamente che cos’è http e come funzionano gli header. Bocchi Cinzia Ultimo aggiornamento: 02/04/2013 1

description

Il documento mostra come "forzare" il download di un file dal server con php.

Transcript of Effettuare il download di un file con PHP

Page 1: Effettuare il download di un file con PHP

Effettuare il download di un file con PHP

Download mediante link direttoVolendo consentire ad un utente del nostro sito di effettuare il download di un file, la prima cosa che viene in mente è di fornire un link diretto. Occorre fare attenzione, però, al fatto che: i file html, pdf e immagine vengono aperti direttamente nel browser ed è possibile

salvarli con “Salva con nome”; i file php vengono processati dal server e non è possibile scaricarli; per tutti gli altri file, il browser chiede di salvare, se non c'è un programma associato in

grado di aprirli.

Esempio

Supponiamo che in una cartella download del web server siano presenti i file:- esempio.html- esempio.jpg- esempio.pdf- esempio.doc

Consideriamo la pagina html seguente:

Il cui codice è:

down.html<!doctype html><html><head>

<meta charset="UTF-8"><title>Download</title>

</head><body>

<p>Clicca sul collegamento per scaricare i file</p><a href="esempio.html">esempio.html</a><br><a href="esempio.jpg">esempio.jpg</a><br><a href="esempio.pdf">esempio.pdf</a><br><a href="esempio.doc">esempio.doc</a>

</body></html>

Se si desidera, invece, forzare il download, indipendentemente dal tipo di file, occorre agire in modo diverso, intervenendo sugli header http. Prima di proseguire, vediamo sinteticamente che cos’è http e come funzionano gli header.

Bocchi CinziaUltimo aggiornamento: 02/04/2013

1

Page 2: Effettuare il download di un file con PHP

Protocollo HTTPIl protocollo HTTP ( Hyper Text Transfer Protocol) è usato come principale sistema per la trasmissione di informazioni sul web. Esso si basa sullo scambio di messaggi. I tipi di messaggi sono due: messaggi di richiesta (HTTP request); messaggi di risposta (HTTP response).

Vediamo, molto in generale, quali sono le caratteristiche di queste due tipologie di messaggi.

HTTP requestLa richiesta è una linea di testo (ASCII) divisa in 3 parti:

Request line – Contiene l’indicazione del metodo HTTP, l’URI, che identifica la risorsa che si vuole ottenere e la versione del protocollo.

Header1 – Contiene alcune informazioni come il nome del server a cui si riferisce l’URI (host) e il tipo di client che ha inviato la richiesta (user agent).

Body – Il contenuto della richiesta.

Le modalità di invio di dati al server sono tipicamente due e dipendono da quale metodo del protocollo http si intende utilizzare: get o post. Esistono comunque anche ulteriori metodi.2

Metodo GETQuando si sceglie il metodo get, le variabili ed il relativo valore vengono fornite allo script destinatario, tramite la barra degli indirizzi del browser. Nell’URL della pagina di risposta potremo vedere tutti i parametri nella barra degli indirizzi (più precisamente nella "query string"). La lista dei parametri, ciascuno nella forma nome_parametro=valore_parametro appare dopo un punto interrogativo, posto alla fine dell'URL. Ogni parametro è separato da quelli adiacenti mediante il simbolo "&".Per esempio, se si inserisce come username “aaa” e come password “bbb”, la query string avrà la forma seguente:

http://miosito/path/login.html?username=aaa&password=bbb

dove miosito è il nome di dominio del sito, cioè il nome che identifica univocamente l’host, e path è il percorso interno alla document root del server che conduce al file login.html.

Metodo POSTQuando si sceglie il metodo post, i dati non compaiono nella query string ma sono contenuti nel messaggio inviato.

HTTP responseIl messaggio di risposta è una linea di testo (ASCII) divisa in 3 parti:

Status line – Contiene un codice di stato, nella seguente forma:

1 Un elenco completo degli header http è reperibile all’url: http://en.wikipedia.org/wiki/List_of_HTTP_header_fields2 Metodi HTTP: http://openskill.info/infobox.php?ID=357

Bocchi CinziaUltimo aggiornamento: 02/04/2013

2

Page 3: Effettuare il download di un file con PHP

- 1xx: Informational (messaggi informativi). - 2xx: Success (la richiesta è stata soddisfatta). - 3xx: Redirection (non c'è risposta immediata, ma la richiesta è sensata e viene

detto come ottenere la risposta). - 4xx: Client error (la richiesta non può essere soddisfatta perché sbagliata). - 5xx: Server error (la richiesta non può essere soddisfatta per un problema interno

del server).3

Header – Contiene alcune informazioni come il tipo e la versione del server (server), il tipo di contenuto restituito (MIME4 type), per esempio text/html, per i documenti HTML, image/jpeg per un’immagine in formato jpeg.

Body – Il contenuto della risposta.

Download mediante modifica degli headerI passi necessari per forzare il download di un file sono i seguenti:1. Modificare il file down.html in modo tale che, cliccando sul link, venga passato al server il pathname del file.2. Creare uno script php (down.php) che recupera il pathname, fa comparire una finestra di dialogo per il download e scrive il file.

Il file html modificato contiene il codice:

down.html<!doctype html><html><head>

<meta charset="UTF-8"><title>Download</title>

</head><body>

<p>Clicca sul collegamento per scaricare i file</p><a href="down.php?filename=esempio.html">esempio.html</a><br><a href="down.php?filename=esempio.jpg">esempio.jpg</a><br><a href="down.php?filename=esempio.pdf">esempio.pdf</a><br><a href="down.php?filename=esempio.doc">esempio.doc</a>

</body></html>

Si osservi che il valore dell’attributo href dell’elemento <a> ha la forma:

script_php?filename=pathname

script_php è il nome del file php definito con il passo 2, filename è il nome del parametro passato al server (viene scelto liberamente dal programmatore) e pathname è il valore del parametro passato al server (il pathname del file). Il metodo usato per inviare il parametro al server è, evidentemente, GET.

Il file php contiene il codice:

3 Per maggiori dettagli consultare http://it.wikipedia.org/wiki/Elenco_dei_codici_di_stato_HTTP4 Un elenco dei tipi MIME più comuni è reperibile all’URL http://en.wikipedia.org/wiki/MIME_type

Bocchi CinziaUltimo aggiornamento: 02/04/2013

3

Page 4: Effettuare il download di un file con PHP

down.php<?php

$filename=$_GET['filename']; header("Content-Disposition: attachment; filename=$filename"); readfile($filename);

?>

La prima riga di codice recupera il parametro passato con la query string e lo assegna alla variabile $filename.

La seconda riga specifica l’header Content-Disposition. Questo header fa apparire una finestra di dialogo per effettuare il download del file. La sua forma generale è la seguente:

Content Disposition: attachment; filename="fname.ext"

dove fname.ext deve essere sostituito dal pathname del file. Nel nostro caso, il pathname è contenuto nella variabile $filename. Si osservi che, per specificare l’header è stata impiegata la funzione php header().La funzione header() non deve essere richiamata dopo che sono stati inviati dei dati al buffer d’uscita, per esempio tramite echo()/print() oppure con del codice HTML esterno ai tag PHP. In tale eventualità verrà sollevato un Warning: Cannot modify header information - headers already sent ...Se non è possibile richiamare le funzioni che manipolano gli header prima dell’invio dei dati, occorre abilitare l’output buffering, inserendo l’invocazione della funzione ob_start() all’inizio del file php. L’abilitazione dell’output buffering fa sì che tutto l’output, ad eccezione degli header, sia inviato ad un buffer interno, dal quale può essere recuperato successivamente5.

La terza riga legge il file e lo scrive nel buffer di output, mediante la funzione php readfile().

Quest'opera è stata rilasciata con licenza Creative Commons Attribution-ShareAlike 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/by-sa/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

5 Per ulteriori dettagli si veda http://www.php.net/ob_start

Bocchi CinziaUltimo aggiornamento: 02/04/2013

4