Guardando i vari newsgroup e forum nei meandri del web, ci si imbatte spesso in domande del tipo: "Sono un webmaster neofita: come posso caricare files sul server con PHP?". In effetti capita spesso di dover effettuare questo tipo di operazioni, soprattutto nel caso di script tipo CMS (Content Manager). Spesso però i vari tutorial consigliano di ricorrere a script già pronti, che però sono altrettanto spesso pesanti e complicati. Quindi perchè non provarci da soli? Come vedremo non si tratta di fare uno script chissà quanto complicato.
Prendiamo il caso in cui vogliate fare l’upload sul server di una semplice immagine gif, dato che questo caso si può estendere a tutti i tipi di file. Bisogna per prima cosa tener conto delle limitazioni di PHP. Per default PHP è configurato con parametro "upload_max_filesize = 2M", che limita la dimensione massima del file da caricare a 2MByte. Il parametro è configurabile se avete accesso alla configurazione di PHP sul server. Per controllare le impostazioni della vostra installazione di PHP eseguite il comando phpinfo() in questo modo:
<?php
phpinfo();
?>
Nella tabella che vi appare cercate il parametro "upload_max_filesize" e verificate la dimensione consentita. Già che ci siete cercate anche il parametro "file_uploads" e verificate che sia su "on". Nel caso sia su "off" dovete impostarla su "on", altrimenti non potrete effettuare alcun tipo di upload. Controllate anche l’impostazione "upload_tmp_dir", che è il percorso della directory in cui il file verrà temporaneamente salvato durante l’operazione di caricamento.
Verificate queste impostazioni iniziali passiamo al codice vero e proprio.
L’interfaccia utente
L’interfaccia utente per l’upload del file è un comunissimo form in HTML:
<form name="upload" method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="uploadfile">
<input type="submit" name="go" value="Carica"></form>
Come si può notare è stato specificato il tipo di codifica dei dati inviati tramite il form con la dicitura ‘enctype="multipart/form-data"’. E’ stato inoltre utilizzato un particolare tipo di campo di input, il tipo "file", che visualizza un campo di testo e un pulsante ‘Sfoglia’ associato, per la ricerca del file. E’ possibile aggiungere un campo di tipo "hidden" denominato "MAX_FILE_SIZE" prima del campo di input di tipo "file". Ad esso si può assegnare un valore che specifica la massima dimensione in bytes del file da caricare, entro i limiti posti da UPLOAD_MAX_FILESIZE. Se vogliamo ad esempio limitare la dimensione ad 1MB si può modificare il codice in questo modo:
<form name="upload" method="post" action="upload.php" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000">
<input type="file" name="uploadfile">
<input type="submit" name="go" value="Carica"></form>
Caricare il file
Passiamo ora ad analizzare il codice che si occupa dell’upload vero e proprio, "upload.php", a cui punta il form soprastante.
Abbiamo detto che trattiamo il caso in cui si voglia fare l’upload di un’immagine gif, possiamo quindi applicare una restrizione per consentire l’upload solo di file di questo formato. Tale restrizione è ovviamente facoltativo e dipende dall’utilizzo che voi farete dello script.
Precisiamo fin da subito che utilizzeremo la viariabile globale $HTTP_POST_FILES, che dalla versione di PHP 4.1.0 è raggiungibile semplicemente come $_FILES. Essa è un array associativo che contiene le informazioni di ogni file caricate. In particolare contiene le seguenti informazioni:
$_FILES['uploadfile']['name'] = nome originale del file sulla macchina dell'utente
$_FILES['uploadfile']['type'] = il MIME-Type del file, se il browser dell'utente fornisce tale informazione (ad esempio "image/gif")
$_FILES['uploadfile']['size'] = dimensione del file caricato in bytes
$_FILES['uploadfile']['tmp_name'] = nome del file temporaneo assegnato al file caricato sul server
$_FILES['uploadfile']['error'] = codice di errore associato al caricamento del file (disponibile da PHP 4.2.0)
Ovviamente "uploadfile" è il nome del file, ovvero quello assegnato precedentemente al campo input di tipo file. I codici di errore possibili sono:
0 = UPLOAD_ERR_OK: nessun errore, l’upload è stato eseguito con successo
1 = UPLOAD_ERR_INI_SIZE: il file caricato eccede la dimensione massima specificata in upload_max_filesize
2 = UPLOAD_ERR_FORM_SIZE: il file inviato eccede le dimensioni specificate nel parametro MAX_FILE_SIZE del form (se presente)
3 = UPLOAD_ERR_PARTIAL: upload eseguito solo parzialmente
4 = UPLOAD_ERR_NO_FILE: il file non è stato caricato
5 = UPLOAD_ERR_NO_TMP_DIR: la cartella temporanea non esiste (da PHP 4.3.10 e PHP 5.0.3)
Il codice dello script è il seguente:
<?php
// controllo che non ci siano stati errori nell'upload (codice = 0)
if ($_FILES['uploadfile']['error'] == 0){
// upload ok
// controllo che il file sia in formato gif
if ($_FILES['uploadfile']['type'] != "image/gif") die("Formato file non valido, è permesso solo il formato gif");
// copio il file dalla cartella temporanea a quella di destinazione mantenendo il nome originale
copy($_FILES['uploadfile']['tmp_name'], "file_caricati/".$_FILES['uploadfile']['name']) or die("Impossibile caricare il file");
// upload terminato, stampo alcune info sul file
echo "Upload terminato con successo:<br>";
echo "Nome file: ".$_FILES['uploadfile']['name']."<br>";
echo "Dimensione file: ".$_FILES['uploadfile']['size']."<br>";
echo "Tipo MIME file: ".$_FILES['uploadfile']['type'];
}
else{
// controllo il tipo di errore
if ($_FILES['uploadfile']['error'] == 2){
// errore, file troppo grande (> 1MB)
die("Errore, file troppo grande: il massimo consentito è 1MB");
}
else{
// errore generico
die("Errore, impossibile caricare il file");
}
}
?>
Analizziamo il codice, anche se i commenti chiariscono già tutto. Per prima cosa controlliamo l’assenza di errori, ovvero codice di errore 0. Se ci sono stati errori, rileviamo il tipo di errore e avvisiamo l’utente chiamando die(), che visualizza un messaggio e blocca lo script. Per rilevare il tipo di errore basta controllare il codice di errore nella variabile $_FILES[‘uploadfile’][‘error’]. Se il codice è 2 significa che il file è troppo grande, poichè eccede le dimensioni del campo MAX_FILE_SIZE del form. E’ inutile chiarire che in questo caso non potrà mai essere codice di errore 1, poichè la condizione sulla dimensione del file è più restrittiva in MAX_FILE_SIZE piuttosto che in UPLOAD_MAX_FILESIZE, quindi se viene superata la dimensione in UPLOAD_MAX_FILESIZE viene ovviamente superata anche la dimensione in MAX_FILE_SIZE. Tutti gli altri casi di errore li consideriamo poi errori generici, in quanto bloccano l’upload del file non per causa dell’utente.
Se tutto va bene, si ricade nel caso UPLOAD_ERR_OK. Controlliamo quindi che il formato del file caricato sia effettivamente gif, anche se, come abbiamo detto, tale restrizione è facoltativa. Per fare ciò basta controllare che il tipo MIME del file sia "image/gif". Nel caso in cui non lo sia si visualizza un messaggio di errore e si interrompe lo script.
A questo punto non rimane che copiare in una directory a nostra scelta il file caricato nella cartella temporanea, utilizzando quindi la funzione copy("file origine", "file destinazione"). Se l’operazione non va a buon fine si visualizza un messaggio di errore e lo script termina, altrimenti si visualizzano alcune informazioni sul file caricato.