Upload: un metodo per caricare file sul server in modo asincrono

L'upload asincrono di un file è una di quellecapacità di AJAX che lo rendono accattivante; permetteinfatti di avviare l' upload di un file semplicemente nelmomento in cui l' utente lo seleziona da un"Dialog Box". In questo tutorial andremo avedere come creare un' applicazione che si basi su questapossibilità.

Come funziona?

  • C'è una semplice tag <form... che contiene il campo <input type="file"...>. Questa form punta ad un IFRAME nascosto che è incaricato dell' upload, accertandosi prima che il file risulti in formato testuale o compresso in .zip
  • La porzione di script chiamata "FILEFRAME" salva il file da caricare, si accerta che non vi siano stati errori durante la procedura e restituisce l' output dell' operazione, dando la possibilità di re-effettuare un nuovo upload
  • L' altra form ha un campo di testo "description" ed uno nascosto "filename". L' utente potrà impostare il campo "description" mentre l' upload è in corso. Terminato l' upoad, l' utente dovrà clickare su "Submit" , così che possa visualizzare le informazioni sul file

Dovremo impostare lo script affinchè vada a salvare ifiles inviatici dagli utenti in una directory: basteràeditare le variabili $upload_dir o$web_upload_dir nel caso si esprima la patch informato filesystem o webserver.

Le funzioni PHP chiamate e sfruttate nello script sono:

  • move_uploaded_file: sposta un file sul webserver
  • fopen: apre in formato testuale un file
  • fwrite: scrive nel file aperto
  • fclose: chiude il file
  • str_replace: sostituisce un tratto di stringa con un altro
  • filesize: restituisce la dimensione di un file in bytes
  • filemtime: restituisce l' orario in cui un file è stato modificato

Non resta che riportare il codice della pagina di upload fileasincrono completa di IFRAME:

<?php$upload_dir = "/var/www/anyexample/aeu"; // Directory completa dove salvare il file caricato$web_upload_dir = "/aeu"; // Directory del webserver dove salvare il file caricato// Controlli sulla directory scelta$tf = $upload_dir.'/'.md5(rand()).".test";$f = @fopen($tf, "w");if ($f == false)die("ERRORE! {$upload_dir} non è scrivibile. Impostare 'chmod 777 {$upload_dir}'o qualcosa di simile che la renda scrivibile");fclose($f);unlink($tf);// fine dei test sulla directory// sezione FILEFRAME dello scriptif (isset($_POST['fileframe'])){$result = 'ERRORE';$result_msg = 'No FILE';if (isset($_FILES['file'])) // il file viene inviato{if ($_FILES['file']['error'] == UPLOAD_ERR_OK) // non ci sono errori{$filename = $_FILES['file']['name']; // festrae il nome del filemove_uploaded_file($_FILES['file']['tmp_name'], $upload_dir.'/'.$filename);// azione principale -- sposta in $upload_dir il file caricato$result = 'OK';}elseif ($_FILES['file']['error'] == UPLOAD_ERR_INI_SIZE)$result_msg = 'Il file che vi vuol caricare supera la dimensione upload_max_filesize impostata in php.ini';else$result_msg = 'Errore sconosciuto';}// scrive codice HTML e JavaScript per l' output dello scriptecho '<html><head><title>-</title></head><body>';echo '<script language="JavaScript" type="text/javascript">'."";echo 'var parDoc = window.parent.document;';if ($result == 'OK'){//Aggiorna lo stato Uploadecho 'parDoc.getElementById("upload_status").value = "Upload effettuato correttamente!";';echo 'parDoc.getElementById("filename").value = "'.$filename.'";';echo 'parDoc.getElementById("filenamei").value = "'.$filename.'";';echo 'parDoc.getElementById("upload_button").disabled = false;';}else{echo 'parDoc.getElementById("upload_status").value = "ERRORE: '.$result_msg.'";';}echo "".'</script></body></html>';exit();}// fine sezione FILEFRAME// Alcune utili funzioni in JavaScript per// rendere innoque tutte le tag HTML ed i simboli speciali// che possono venir inseriti dagli utentifunction safehtml($s){$s=str_replace("&" , "&amp;" , $s);$s=str_replace("<" , "&lt;" , $s);$s=str_replace(">" , "&gt;" , $s);$s=str_replace("'" , "&apos;" , $s);$s=str_replace(""" , "&quot;" , $s);return $s;}if (isset($_POST['description'])){$filename = $_POST['filename'];$size = filesize($upload_dir.'/'.$filename);$date = date('r', filemtime($upload_dir.'/'.$filename));$description = safehtml($_POST['description']);// Genera la pagina di informazioni$html =<<<END<html><head><title>{$filename} [Prova upload]</title></head><body><h1>{$filename}</h1><p>questa è la pagina di informazione sull upload del file. Aggiungerla ai segnalibri, or inviarla...</p><p>Data: {$date}</p><p>SDimensione: {$size} bytes</p><p>Descrizione:<pre>{$description}</pre></p><p><a href="{$web_upload_dir}/{$filename}" style="font-size: large;">download file</a><br><a href="{$PHP_SELF}" style="font-size: small;">torna alla pagina di upload</a><br><a href="{$web_upload_dir}/upload-log.html" style="font-size: small;">upload-log</a></p></body></html>END;// salva l' HTML$f = fopen($upload_dir.'/'.$filename.'-desc.html', "w");fwrite($f, $html);fclose($f);$msg = "File {$filename} uploaded,<a href='{$web_upload_dir}/{$filename}-desc.html'>see file information page</a>";// Salva il LOG dell' upload$f = fopen($upload_dir."/upload-log.html" , "a");fwrite($f, "<p>$msg</p>");fclose($f);// imposta il messaggio nella cookiessetcookie('msg', $msg);// rediretta alla pagina principale dello scriptheader("Location: http://".$_SERVER['HTTP_HOST'].$PHP_SELF);exit();}// ricava il messaggio dalla cookieif (isset($_COOKIE['msg']) && $_COOKIE['msg'] != ''){if (get_magic_quotes_gpc())$msg = stripslashes($_COOKIE['msg']);else$msg = $_COOKIE['msg'];// cancella la cookie per evitare la ripetizione dello stesso messaggiosetcookie('msg', '');}?><!-- Inizio della pagina principale --><html><head><title>Esempio Upload File</title></head><body><?phpif (isset($msg))echo '<p style="font-weight: bold;">'.$msg.'</p>';?><h1>Upload file:</h1><p>Il file verrà caricato non appena verrà scelto. </p><p>Mentre è in corso l' upload del file, è possibile scriverne una breve descrizione.</p><form action="<?=$PHP_SELF?>" target="upload_iframe" method="post" enctype="multipart/form-data"><input type="hidden" name="fileframe" value="true"><label for="file">text file uploader:</label><br><input type="file" name="file" id="file" onChange="jsUpload(this)"></form><script type="text/javascript">/* Funzione chiamata quando l' utente seleziona il file da caricare */function jsUpload(upload_field){//Controlla che il file da caricare sia in formato testuale o .zipvar re_text = /.txt|.xml|.zip/i;var filename = upload_field.value;/* Checking file type */if (filename.search(re_text) == -1){alert("Il file non è testuale(txt, xml, zip)");upload_field.form.reset();return false;}upload_field.form.submit();document.getElementById('upload_status').value = "caricamento file...";upload_field.disabled = true;return true;}</script><iframe name="upload_iframe" style="width: 400px; height: 100px; display: none;"></iframe><!-- Nel caso si voglia il debug, bisognerà rimuovere il"display: none" dall' attributo style="" --><br>Stato Upload:<br><input type="text" name="upload_status" id="upload_status"value="no upload" size="64" disabled><br><br>Nome File:<br><input type="text" name="filenamei" id="filenamei" value="none" disabled><form action="<?=$PHP_SELF?>" method="POST"><input type="hidden" name="filename" id="filename"><br><br><label for="photo">Descrizione File:</label><br><textarea rows="5" cols="50" name="description"></textarea><br><br><input type="submit" id="upload_button" value="save file" disabled></form><br><br><a href="<?=$web_upload_dir?>/upload-log.html">upload-log</a><br><br></body></html>