#PHP Creare un form upload

Costruire un modulo per allegare file

Autore: Andrea Pacchiarotti
Ultimo aggiornamento: 07 Dicembre 2019
Categoria: Web Marketing Costruzione siti web Form PHP

PHP form
#PHP Creare un form upload

In questo utile e pratico articolo vedremo come costruire un modulo per allegare file o, per dirla in maniera più tecnica capiremo come creare un form upload in PHP. Partiremo con la spiegazione del semplice invio dell'allegato fino ad arrivare ad un form che contemplerà, oltre all'allegato, ulteriori campi (destinatario, mittente, oggetto e messaggio). Se sei a corto di nozioni leggi prima Come inviare un form creato in HTML.

  1. Creare il modulo di upload in HTML
  2. Creare il codice PHP che permette l'upload
  3. Implementazione dei controlli
    1. Verificare che il file non sia troppo grande
    2. Verificare che l'upload non sovrascriva un altro file
    3. Verificare l'estensione del file caricato
    4. Verificare se il file è effettivamente un’immagine
  4. Upload di una serie di file
  5. Creare il modulo di upload insieme ad ulteriori campi

Creare il modulo di upload in HTML

Per effettuare il caricamento (upload) di un file sul server, in questo esempio di un’immagine .jpg o .png, occorre creare un modulo (form) in HTML, corredato eventualmente da un po’ di CSS, per permettere all’utente la selezione del file dal proprio computer e il successivo invio tramite il metodo POST.
Ecco, limitato allo stretto necessario, il codice HTML del form di upload:

<form enctype="multipart/form-data" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="4194304">
Carica un'immagine in formato jpg o png<br>
<input type="file" name="immagine"><br><br>
<input type="submit" value="Invia"><br>
Il tempo di caricamento dipende dalla tua velocità di connessione. <br>
Attendi la scritta: "File inviato con successo." per essere sicuro di aver spedito il file.
</form>

Due parole di spiegazione:

Creare il codice PHP che permette l'upload

PHP prevede una variabile superglobale $_FILES, ovvero un vettore (array) con le informazioni sul file caricato; l'array ha la seguente struttura:

Ecco il codice, in versione minimale, per recuperare il file e metterlo nella cartella mioupload, creata da noi all’interno del server, che ospiterà i file caricati dall’utente attraverso il form:

<?php
// verifico, attraverso la funzione is_uploaded_file, che il file sia stato caricato
if (!isset($_FILES['immagine']) || !is_uploaded_file($_FILES['immagine']['tmp_name'])) {
echo 'File non inviato';
exit;   
}

//imposto il percorso della cartella dove mettere il file caricato dall’utente
$uploaddir = 'mioupload/';

//recupero il percorso temporaneo del file
$immagine_tmp = $_FILES['immagine']['tmp_name'];

//recupero il nome originale del file caricato
$immagine_name = $_FILES['immagine']['name'];

// verifico, attraverso la funzione move_uploaded_file, se il file è stato spostato nella cartella mioupload del server
if (move_uploaded_file($immagine_tmp, $uploaddir . $immagine_name)) {
echo 'File inviato';
}else{
echo 'Caricamento invalido';
}
?>

Due parole di spiegazione anche qui:

Implementazione dei controlli

La verifica sul fatto che il file sia stato caricato, è già presente all’inizio del codice minimale appena proposto, ecco ulteriori verifiche.

Verificare che il file non sia troppo grande

// limito la dimensione massima a 4MB
if ($_FILES['immagine']['size'] > 4194304) {
echo 'Il file non può eccedere i 4 MB';
exit;
}

Verificare che l'upload non sovrascriva un altro file

$target_file = 'mioupload/' . $_FILES['immagine']['name'];
if (file_exists($target_file)) {
echo 'Il file esiste già';
exit;
}

La funzione file_exists(path) controlla se esiste un file o una directory

Verificare l'estensione del file caricato

Ovviamente si può mettere qualsiasi estensione, qui sono presenti solo quelle di alcuni tipi di immagine, ma tale controllo è molto importante per evitare di essere attaccati con l’invio di codici che potrebbero compromettere la sicurezza del nostro server.

$ext_ok = array('jpg', 'jpeg', 'png');
$temp = explode('.', $_FILES['immagine']['name']);
$ext = end($temp);
if (!in_array($ext, $ext_ok)) {
echo 'Puoi caricare solo file jpg o png';
exit;
}

La funzione in_array(search, array, type) cerca un valore specifico in una matrice.

Verificare se il file è effettivamente un’immagine

$is_img = getimagesize($_FILES['immagine']['tmp_name']);
if (!$is_img) {
echo 'Puoi inviare solo un’immagine';
exit;   
}

Upload di una serie di file

<form enctype="multipart/form-data" action="upload.php" method="POST">
<p>Fotografie:
<input type="file" name="pic []">
<input type="file" name="pic []">
<input type="file" name="pic []">
<input type="submit" value="Invia">
</p>
</form>
<?php
foreach ($_FILES["pic"]["error"] as $key => $error) {
    if ($error == UPLOAD_ERR_OK) {
        $tmp_name = $_FILES["pic"]["tmp_name"][$key];
        $name = $_FILES["pic"]["name"][$key];
        move_uploaded_file($tmp_name, "data/$name");
    }
}
?>

Creare il modulo di upload insieme ad ulteriori campi

Per inviare una mail con allegato, ma questa volta insieme ad altri campi, è possibile sfruttare la funzione mail() del PHP, mentre per spedire l'allegato interverremo nella proprietà filename del messaggio. Ecco il codice PHP completo:

<?php
// Recupero il valore dei campi del modulo
$destinatario = 'pacchiarotti@gmail.com';
$mittente = $_POST['mittente'];
$oggetto = $_POST['oggetto'];
$messaggio = $_POST['messaggio'];
// Valorizzo le variabili relative all'allegato
$allegato = $_FILES['allegato']['tmp_name'];
$allegato_type = $_FILES['allegato']['type'];
$allegato_name = $_FILES['allegato']['name'];
// Creo due variabili per uso interno
$headers = "From: " . $mittente;
$msg = "";
// Verifico se il file è stato caricato correttamente via HTTP, in caso positivo proseguo
if (is_uploaded_file($allegato))
{
// Apro e leggo l'allegato
$file = fopen($allegato,'rb');
$data = fread($file, filesize($allegato));
fclose($file);
// Adatto il file al formato MIME base64 usando base64_encode
$data = chunk_split(base64_encode($data));
// Genero il separatore per dividere la parte testuale dall'allegato
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// Aggiungo le intestazioni per l'allegato
$headers .= "\nMIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed;\n";
$headers .= " boundary=\"{$mime_boundary}\"";
// Definisco il tipo di messaggio (MIME/multi-part)
$msg .= "This is a multi-part message in MIME format.\n\n";
// Metto il separatore
$msg .= "--{$mime_boundary}\n";
// Ecco la parte testuale del messaggio
$msg .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$msg .= "Content-Transfer-Encoding: 7bit\n\n";
$msg .= $messaggio . "\n\n";
// Metto il separatore
$msg .= "--{$mime_boundary}\n";
// Ecco l'allegato
$msg .= "Content-Disposition: attachment; filename=\"{$allegato_name}\"\n";
$msg .= "Content-Transfer-Encoding: base64\n\n";
$msg .= $data . "\n\n";
// Chiudo con il separatore
$msg .= "--{$mime_boundary}--\n";
}
// Se non è stato caricato alcun file preparo un messaggio
else
{
$msg = $messaggio;
}
// Invio la mail
if (mail($destinatario, $oggetto, $msg, $headers))
{
echo "Mail inviata con successo!";
}else{
echo "Errore!";
}
?>

Scarica i codici per il form in PHP


Per saperne di più sul Web Marketing potrebbero interessarti questi libri:


Se vuoi approfondire alcuni dei temi trattati, visita la pagina con le mie pubblicazioni cartacee e online.

Se l'articolo ti è piaciuto, condividilo!

Segui l'hashtag #AndreaPacchiarotti