Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Upload con Php

Realizzare un modulo per l'upload su uno spazio remoto via web
Realizzare un modulo per l'upload su uno spazio remoto via web
Link copiato negli appunti

Premessa

Come è noto a chiunque abbia un minimo di familiarità con il PHP, è estremamente semplice gestire gli Uploads da un computer-client verso un
computer-server. Lo scopo di questo articolo è proprio dimostrarlo e realizzare, alla fine, un
semplice script che ci consenta di gestire agevolmente il "caricamento" dei file in rete.

Piccola, ma doverosa, premessa: cosa significa Upload?
Letteralmente questa parola inglese
significa "caricare" e si contrappone, logicamente, a Download (termine probabilmente più
familiare del primo), ossia "scaricare".
In breve indica l'operazione di trasferimento di uno o
più files da un client verso un server, operazione che di norma viene svolta avvalendosi del
protocollo FTP (File Transfer Protocol) e di appositi programmi (detti appunto client FTP).
Ma il trasferimento può anche essere attuato, con PHP, tramite un form con metodo POST; ed è proprio questo
il caso che stiamo prendendo in considerazione.

PHP, si diceva, può ricevere files "uploadati" da qualunque browser che sia compatibile con le
direttive fissate nella RFC (Request For Comments) 1867 che, nel lontano Novembre 1995
(preistoria per gli standard di Internet...), introduceva un nuovo tipo di opzione per i campi
di un modulo di tipo input: l'opzione FILE. Inoltre veniva definito un nuovo MIME (Multipurpose Internet
Mail Extensions) media type, denominato multipart/form-data (per maggiori informazioni in
merito, si può leggere l'intera RFC a questo indirizzo http://www.ietf.org/rfc/rfc1867.txt).

Costruzione del modulo html

Fatta questa premessa introduttiva, possiamo adesso cominciare a costruire il nostro script
per gli Uploads. Il primo passo non può che essere la realizzazione del modulo HTML che ci
servirà per inviare i nostri files al server; ridotto al suo schema essenziale, il form può
essere così concepito:

<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="upfile">
<input type="hidden" name="MAX_FILE_SIZE" value="10000">
<input type="submit" value="Invia il file">
</form>

Salviamo queste righe in un file chiamato form.html (non è necessaria l'estensione
.php, dato che contiene solo istruzioni html).

Un prima considerazione si impone: oltre al campo di tipo FILE, abbiamo aggiunto un campo
nascosto (hidden) chiamato MAX_FILE_SIZE con value 10000. Esso indica la 'grandezza' massima
(espressa in bytes) del file da caricare e a questo proposito va detto che, come avverte
chiaramente anche il manuale ufficiale di PHP, non si deve fare troppo affidamento su questo
parametro per "garantirsi" contro gli upload di files di dimensioni maggiori di quella
desiderata, perchè il limite è facilmente aggirabile.

Molto più sicuro, a questo fine, è il
parametro upload_max_filesize nel file php.ini (il file di configurazione di PHP) che di
default è settato a 2 MegaBytes.

Seconda considerazione: adesso che abbiamo il nostro modulo per l'upload, una cosa che balza subito
all'occhio è il tasto "sfoglia" (browse) alla destra del campo di tipo FILE;
questo bottone serve proprio per selezionare il file dall'hard disk del client che verrà visualizzato (il file, non l'Hard Disk...), all'interno del campo, con il suo percorso assoluto.

Le variabili da usare per l'upload

Prima di addentrarci nella realizzazione della pagina PHP che "raccoglierà" i dati provenienti
dal modulo, è necessario spiegare cosa accade quando lo script riceve un Upload.

In questa situazione vengono
automaticamente definite alcune variabili particolari, caratterizzate anzitutto dal fatto che
il loro nome consta di due parti: la prima coincide con il nome del campo di tipo FILE (nel
nostro caso quindi upfile); la seconda invece indica un "attributo" del file.

Da notare altresì che queste variabili saranno disponibili all'interno dell'array globale
$HTTP_POST_FILES ($_FILES a partire da PHP 4.1.0), sempre che il parametro track_vars, nel file
php.ini, sia settato ad ON (il problema, peraltro, si pone per le versioni di PHP precedenti
alla 4.03, a partire dalla quale track_vars è automaticamente abilitato).

Queste variabili sono:

  • $nomefile (il nome temporaneo del file che viene attribuito al file sul server)
  • $nomefile_name (il nome originario o il percorso del file sul client)
  • $nomefile_size (la grandezza, espressa in bytes, del file)
  • $nomefile_type (il MIME type del file, ad esempio application/x-zip-compressed)

Come detto $nomefile si riferisce al nome del campo FILE del form, quindi $upfile nel nostro
esempio.

A questo punto però, è doveroso accennare alla grande modifica introdotta dallo staff di PHP a
partire dalla versione 4.2.0 (al momento in cui scrivo siamo arrivati alla 4.2.3), ossia il
settaggio ad Off di default del parametro register_globals nel file php.ini.

Senza approfondire troppo l'argomento, in quanto esulerebbe dagli scopi di questo scritto, possiamo
limitarci a dire che, a seguito di questa novità per riferirsi alle variabili globali,
occorre fare riferimento all'array cui esse appartengono (a meno che non si modifichi php.ini,
ovviamente). Nel nostro caso, quindi, all'array $HTTP_POST_FILES sostituiamo l'array $_FILES (in seguito vedremo come rendere comunque compatibili anche le versioni
di PHP precedenti alla 4.1.0).

Quindi le variabili si "traducono" in:

  • $_FILES["nomefile"]["tmp_name"] (il nome temporaneo del file che viene attribuito al file sul server)
  • $_FILES["nomefile"]["name"] (il nome originario o il percorso del file sul client)
  • $_FILES["nomefile"]["size"] (la grandezza, espressa in bytes, del file)
  • $_FILES["nomefile"]["type"] (il MIME type del file, ad esempio application/x-zip-compressed)

Costruiamo la pagina Php per l'upload

Cominciamo quindi a costruire la pagina .php che si occuperà di verificare l'upload e di gestire
il file come vogliamo. Per comodità, preferisco scrivere prima tutto il codice e poi spiegarlo
passo passo, con l'avvertenza che anche qui, come nel form, lo script sarà semplice, senza troppe opzioni.

<?

// QUESTE RIGHE RENDONO LO SCRIPT COMPATIBILE CON LE VERSIONI
// DI PHP PRECEDENTI ALLA 4.1.0
if(!isset($_FILES)) $_FILES = $HTTP_POST_FILES;
if(!isset($_SERVER)) $_SERVER = $HTTP_SERVER_VARS;

/********************* VARIABILI DA SETTARE ********************/
// Directory dove salvare i files Uploadati ( chmod 777, percorso assoluto)
$upload_dir = $_SERVER["DOCUMENT_ROOT"] . "/upload";

// Eventuale nuovo nome da dare al file uploadato
$new_name = "";

// Se $new_name è vuota, il nome sarà lo stesso del file uploadato
$file_name = ($new_name) ? $new_name : $_FILES["upfile"]["name"];

if(trim($_FILES["upfile"]["name"]) == "") {

die("Non hai indicato il file da uploadare !");

}

if(@is_uploaded_file($_FILES["upfile"]["tmp_name"])) {

@move_uploaded_file($_FILES["upfile"]["tmp_name"], "$upload_dir/$file_name")
or die("Impossibile spostare il file, controlla l'esistenza o i permessi della directory dove fare l'upload.");

} else {

die("Problemi nell'upload del file " . $_FILES["upfile"]["name"]);

}

echo "L'upload del file " . $_FILES["upfile"]["name"] . " è avvenuto correttamente";

?>

Le prime righe, come chiarisce il commento, servono a rendere disponibile la sintassi dei nuovi
array introdotti con PHP 4.1.0 anche alle versioni precedenti.

Le due variabili da settare sono rispettivamente:

  • la directory dove spostare i files
    uploadati ($upload_dir, da indicare con il percorso assoluto sul server e i cui permessi
    vanno settati a 777)
  • l'eventuale nuovo nome da dare al file che viene caricato sul server
    ($new_name; se non si vuole rinominare il file, questo avrà lo stesso nome che aveva sul
    computer client.)

A questo punto effettuiamo un controllo per verificare se è stato selezionato un file per
l'Upload, e lo facciamo con riferimento alla proprietà "name" del file.

Andata a buon fine questa verifica, possiamo passare al cuore dello script, la parte cioè che
"sposta" il file caricato in rete dalla directory temporanea del server (che si può settare in
php.ini, nella variabile upload_tmp_dir) alla directory da noi indicata, eventualmente
rinominandolo.

Le funzioni usate a questo scopo, sono is_uploaded_file() (PHP 3>= 3.0.17, PHP 4 >= 4.0.3)
e move_uploaded_file() (PHP 4 >= 4.0.3, eventualmente si può usare copy() in sostituzione).
La
prima funzione prende come parametro la variabile che contiene il nome temporaneo del file uploadato
sul server ($_FILES["upfile"]["tmp_name"]) e verifica, appunto, se sia stato caricato; la
seconda funzione prende due parametri: il primo è il nome temporaneo ed il secondo è il percorso
finale (comprensivo del nome, nuovo o meno, del file) dove spostarlo.

A questo proposito vi segnalo che è possibile, nell'ipotesi in cui si disponga di una versione
di PHP in cui non sia presente la funzione is_uploaded_file(), "costruirne" una che svolga lo
stesso compito, come evidenziato dal manuale ufficiale a questo link:
http://www.php.net/manual/it/features.file-upload.php.

Se anche queste operazioni si svolgono senza problemi (nel caso di difficoltà, lo script
restituirà solo messaggi d'errore personalizzati), verrà stampata a video la frase che ci
conferma che l'upload è avvenuto correttamente.

Conclusioni

Tutto molto semplice come si vede. Ovviamente è possibile implementare ulteriori controlli
all'interno dello script; ad esempio, sfruttando la proprietà "type", si può agevolmente limitare
l'upload solo a determinati tipi di files aggiungendo poche righe subito dopo il controllo sull'esistenza del file uploadato:

<?

$allowed_types = array("image/gif","image/x-png","image/pjpeg","image/jpeg");
if(!in_array($_FILES["upfile"]["type"],$allowed_types)) {

die("Il file non è di un tipo consentito, sono ammessi solo i seguenti: " . implode(",", $allowed_types) . ".");

}

?>

Sulla base di questo esempio, sarebbe consentito solo l'upload di immagini .gif, .png e .jpg
(o .jpeg).

Ti consigliamo anche