Upload multiplo di immagini con PHP

Giovanni Canella

08/10/2013

6236

In PHP il caricamento di immagini o di files in generale, sul proprio server è una procedura molto semplice e ci potrà risultare molto utile in diversi ambiti: In questo articolo vedremo come impostare il tutto con la massima sicurezza possibile per evitare eventuali sorprese "indesiderate".

Questo perchè se non inseriamo opportuni controlli, l'utente può caricare anche file con estensione .php, iniettando di conseguenza codice che può compromettere l'integrità della nostra applicazione, in maniera del tutto  "invisbile". Per nostra fortuna bastano pochi accorgimenti.

HTML

Prima di vedere il sistema di caricamento in PHP, dobbiamo creare il form HTML per permettere all'utente di selezionare le immagini che desidera

<form method="post" enctype="multipart/form-data" action="carica.php" id="form">
	<h1>Upload immagini PHP</h1>
	<hr>

	<label for="file">Seleziona l'immagine da caricare: </label>
	<input type="file" name="file[]" multiple/>

	<input type="submit" name="carica" value="Carica" />
</form>

Uniche note rilevanti sono, l'utilizzo della proprietà enctype che stabilisce con che metodo i dati devono essere codificati prima dell'invio al server. Accetta i seguenti 3 parametri:

  • application/x-www-form-urlencoded: (Default) Codifica gli spazi, con il "+" e i caratteri speciali con il relativo codice ASCII (American Standard Code for Information Interchange) in formato esadecimale,
  • text/plain: Identico a quello sopra illustrato a parte il fatto che i caratteri speciali non vengono codificati,
  • multipart/form-data: Quello utilizzato nel nostro form, indispensabile per la corretta esecuzione del nostro sistema di caricamento, dato che i dati non vengono codificati per permettere appunto l'upload del file.

N.B = Questa proprietà è associabile solo se il metodo è impostato su "post".

Altra nota rilevante è l'utilizzo dell'attributo: multiple all'interno del tag input, per permette di selezionare più elementi, per una maggiore comodità: altrimenti bisgonerebbe caricare ogni volta la pagina per eseguire l'upload di un solo file!

CSS

Ora diamo un tocco di stile al nostro form con qualche regola CSS:

* {
	margin: 0;
	padding: 0;
	font-family: Arial, Helvetica, sans-serif;
}

body {
	background-color: #CCC;
}

#form {
	width: 700px;
	height: 250px;
	margin: 50 auto;
	padding: 20px;
	background-color: #FFF;
	border-radius: 10px;
}

.elemento {
	margin-top: 10px;
}

input {
	display: block;
	margin-top: 5px;
}

input[type="submit"] {
	padding: 8px;
}

Ecco il risultato:

Form per upload immagini PHP

PHP

Ora veniamo alla parte principale, in cui andremo a scrivere il codice per gestire tutto il meccanismo precedentemente illustrato. Quando inviamo il form cliccando su "Carica", verrà instaurata una connessione verso la pagina carica.php, in cui verranno passati i vari dati nel form, nel nostro caso l'immagine che verrà salvata temporaneamente in una cartella del server. PHP nello stesso momento imposterà la variabile superglobale $_FILES (un array multidimensionale), che conterrà tutti i dettagli di cui abbiamo bisogno:

  • $_FILES["file"]["name"]: Il nome d'origine del file caricato,
  • $_FILES["file"]["size"]: La dimensione del file rappresentata in byte,
  • $_FILES["file"]["tmp_name"]: Il nome temporaneo dato al file caricato,
  • $_FILES["file"]["error"]: Eventuali errori intercettati durante l'esecuzione, utile per impostare dei controlli prima di mettere mano al file.

carica.php

if(!empty($_FILES["file"])) {
	foreach ($_FILES["file"]["name"] as $indice => $nome) {
		if($_FILES["file"]["error"][$indice] == 0) {
			$estensione = pathinfo($_FILES["file"]["name"][$indice], PATHINFO_EXTENSION);

			if($estensione == "png" || $estensione == "jpg") {
				if($_FILES["file"]["size"][$indice] < 1000000) {
					$risultato = move_uploaded_file($_FILES["file"]["tmp_name"][$indice], $_SERVER["DOCUMENT_ROOT"] . "/" . $_FILES["file"]["name"][$indice]);
					if($risultato) {
						echo "File spostato con successo!";
					} else {
						die("Errore imprevisto durante lo spostamento dell'immagine! :(");
					}
				} else {
					die("Il file selezionato è troppo grande, non deve superare 1MB!");
				}
			} else {
				die("Estensione non consentita! Hai cercato di caricare un file ." . $estensione . "!");
			}
		} else {
			die("Errore imprevisto durante il caricamento dell'immagine! :(");
		}
	}
} else {
	die("Nessun file selezionato.");
}

Come prima cosa controlliamo se l'utente ha inserito almeno un'immagine, successivamente le scorriamo tutte (tramite foreach) senza porci il problema se è solo una, dato che il ciclo non verrà ripetuto più di quanto necessario. In questo modo andremo a specificare l'$indice per accedere alle immagini nell'array globale $_FILES

$_FILES["file"]["size"][$indice] < 1000000

Ora che abbiamo il controlla sulla singola immagine possiamo procedere ai controlli di sicurezza, verificando che estensione ha il file, ottenendo il valore desiderato da pathinfo() con PATHINFO_EXTENSION come parametro passato. Altro controllo è per la dimensione del file, dove scartiamo quelli superiori a 1MB di peso, già elevato per un'immagine.

Se tutto fila liscio allora procediamo allo spostamento dalla cartella temporanea a quella che vogliamo, tramite move_uploaded_file(), impostando il nome a ginho-[NOME DELL'IMMAGINE CARICATA].

Conclusioni

In pochi semplici passaggi siamo riusciti a realizzare un sistema di caricamento semplice e sicuro, con cui possiamo anche caricare più immagini alla volta. Volendo ulteriormente migliorarlo è possibile utilizzare AJAX.

Ti potrebbero interessare

I più letti