back to top

Archiviare immagini in un database usando PHP e MySQL

1. Introduzione: archiviazione delle immagini in MySQL

Innanzitutto poniamoci una domanda: è possibile allocare immagini sotto forma di informazioni all’interno di un database? Naturalmente è possibile; nello stesso modo sarà possibile gestire queste informazioni, modificarle ed estrarle utilizzando gli stessi comandi SQL che normalmente vengono impiegati per l’amministrazione di stringhe ed interi.

Potremo quindi usare il comando INSERT per l’archiviazione delle immagini, SELECT per la loro estrazione e così via; PHP costituirà un’interfaccia ideale per automatizzare tutti i processi di amministrazione delle immagini conservate all’interno di un database, che nel nostro caso sarà un archivio creato tramite il DBMS MySQL.

Ma quali sono i vantaggi nel preferire l’allocazione delle immagini in tabelle piuttosto che in semplici cartelle salvate nella root del Web server? Vediamone alcuni:

  • sarà possibile salvare in ogni momento i nostri dati tramite una semplice esportazione (Dump) delle tabelle; è certamente molto più semplice, veloce e sicuro un singolo comando di esportazione tramite Shell o PhpMyAdmin, piuttosto che il download via FTP di centinaia di file sparsi nel nostro spazio web;
  • non sarà più possibile accedere direttamente alle immagini tramite URL, con indubbi vantaggi relativi alla sicurezza dei dati.
  • non si avranno più problemi relativi ai percorsi di accesso alle immagini, queste infatti si troveranno all’interno di un database raggiungibile attraverso la medesima procedura da una qualsiasi pagina indipendentemente dalla sua posizione;
  • non sarà più necessario settare permessi sulle cartelle, questo diminuirà l’esigenza di accedere al nostro spazio tramite FTP con conseguente risparmio di tempo.
Naturalmente non dovremo ignorare alcuni possibili svantaggi di questa metodologia, li esporremo in modo che il lettore possa valutare quale sistema preferire tra la classica allocazione delle immagini in cartelle e quella in tabelle:
  • l’archiviazione di file nel database può comportare dei rischi di insuccesso nell’INSERT e nella SELECT delle informazioni per documenti di grandi dimensioni;
  • sarà possibile accedere alle nostre immagini soltanto tramite comandi SQL;
  • le immagini mediamente "pesano" molto più dei testi e i nostri database diverranno in poco tempo molto ampi.
Detto questo, passiamo alla creazione di una tabella progettata per la gestione delle immagini:
$sql = 'CREATE TABLE `immagini` ('
. ' `id` int(11) NOT NULL auto_increment,'
. ' `nome` varchar(50) NOT NULL default "",'
. ' `size` varchar(25) NOT NULL default "",'
. ' `type` varchar(25) NOT NULL default "",'
. ' `immagine` blob NOT NULL,'
. ' PRIMARY KEY (`id`)'
. ' )';
Il campo destinato all’allocazione delle immagini sarà quello caratterizzato dal tipo di dato BLOB (Binary Large Object) specificamente dedicato al trattamento di questa tipologia di informazioni.

2. Upload dei file in MySQL

Per l’invio delle immaginii file nella nostra tabella denominata "immagini", utilizzeremo il classico sistema basato su un form per l’invio dei parametri di input e di un sorgente PHP dedicato all’elaborazione di questi ultimi.

Nel caso specifico, creeremo una funzione destinata alla raccolta dei dati tramite form e all’inserimento di questi ultimi nel database:

<?
function upload()
{
  $result = false;
  $immagine = '';
  $size = 0;
  $type = '';
  $nome = '';
  $max_size = 300000;
  $result = @is_uploaded_file($_FILES['file']['tmp_name']);
  if (!$result)
  {
    echo "Impossibile eseguire l'upload.";
    return false;
  }else{
    $size = $_FILES['file']['size'];
    if ($size > $max_size)
    {
      echo "Il file è troppo grande.";
      return false;
    }
    $type = $_FILES['file']['type'];
    $nome = $_FILES['file']['name'];
    $immagine = @file_get_contents($_FILES['file']['tmp_name']);
    $immagine = addslashes ($immagine);
    @include 'config.php';
    $sql = "INSERT INTO immagini (nome, size, type, immagine) VALUES ('$nome','$size','$type','$immagine')";
    $result = @mysql_query ($sql) or die (mysql_error());
    return true;
  }
}
?>
L’impianto della funzione upload() è abbastanza semplice, in pratica lo script riceve i dati dal form, controlla che l’upload sia avvenuto correttamente tramite la funzione is_uploaded_file(), quindi, esegue un secondo controllo sulla grandezza dell’immagine che non deve superare i 30.000 byte.

Una volta eseguite le opportune verifiche, la funzione da il via alla query d’inserimento dei dati all’interno della tabella. Da notare come le informazioni relative all’immagine vengano raccolte tramite la superglobale $_FILES, mentre i contenuti binari del file sono estrapolati tramite la funzione file_get_contents().

Nello script viene richiamato, tramite un’inclusione, anche il classico file di configurazione contenente i parametri necessari alla connessione a MySQL e alla selezione del database:

<?
$host = 'localhost';
$username = 'user';
$password = 'password';
$db = 'img';
$conn = @mysql_connect($host,$username,$password) or die (mysql_error());
$sel = @mysql_select_db($db) or die (mysql_error());
?>

3. Form per il caricamento delle immagini in MySQL

Nell’articolo precedente, abbiamo proposto il codice necessario per la creazione di una funzione destinata alla ricezione di input sotto forma di dati binari e all’inserimento di questi ultimi nella tabella di un database creato tramite MySQL.

Ora descriveremo il listato che potrebbe essere utilizzato per la generazione di un form destinato all’invio dei parametri di input:

<?
@include 'upload.php';
if (isset($_FILES['file']))
{
  upload();
}
echo "
<h3>Upload</h3>
<form enctype=\"multipart/form-data\" 
action=\"".$_SERVER['PHP_SELF']."\" method=\"post\">
<input type=\"hidden\" name=\"MAX_FILE_SIZE\" 
value=\"300000\" />
<input type=\"file\" name=\"file\" size=\"40\" />
<input type=\"submit\" value=\"Invia\" />
</form>
<br /><a href=\"link.php\">Elenco</a>";
?>
Innanzitutto, viene incluso il file upload.php nel quale abbiamo salvato il codice della funzione per l’elaborazione e l’inserimento dei dati, il lettore potrà tranquillamente utilizzare un nome a suo piacimento, non fà alcuna differenza se l’estensione del file rimane ".php".

In secondo luogo viene effettuato un controllo, infatti, se la variabile superglobale $_FILES è stata settata, ciò vuol dire che il parametro di input è stato già inviato e si dovrà procedere con l’allocazione del dato, per far questo si passerà quindi alla chiamata della funzione upload().

In caso contrario, se cioè la superglobale non è stata valorizzata, verrà visualizzato il form per l’inserimento dei dati.

Il form, nel nostro caso prevederà un unico campo di input destinato al caricamento del file da uploddare. Da notare come per l’invio di file tramite modulo sia necessario specificare nel delimitatore di apertura del form il costrutto enctype="multipart/form-data", con il quale segnaliamo che i parametri inviati non saranno unicamente testuali.

Nel form troviamo questa specifica name="MAX_FILE_SIZE" value="300000" all’interno di un campo nascosto, grazie ad essa stabiliamo che i file destinati all’upload non dovranno superare la dimensione massima di 30.000 byte. Questo accorgimento sarà utile per l’utente nel momento in cui dovrà effettuare l’upload, se infatti l’immagine dovesse essere troppo grande, riceverà immediatamente una notifica indicante l’impossibilità di effettuare il caricamento.

Chiuso il form, troviamo un link al file link.php che si occuperà di elencare i link ai file caricati in tabella.

4. Ottenere l’elenco dei file allocati in tabella

Come anticipato nel precedente articolo, una volta eseguito l’upload dei binari in tabella, sarà utile creare un elenco completo dei dati disponibili. Procederemo in questo modo: salveremo in un file, chiamato ad esempio link.php, una query che ci restituirà dei collegamenti alle varie immagini allocate nel database.

I collegamenti saranno relativi ai diversi Id autoincrementali e ognuno di essi farà riferimento al file per la visualizzazione delle immagini di cui parleremo nel capitolo seguente:

<?
@include 'config.php';
$sql = "SELECT id, nome FROM immagini ORDER BY id DESC";
$result = @mysql_query($sql) or die (mysql_error ());
while ($row = @mysql_fetch_array($result))
{
  $id = $row['id'];
  $nome = $row['nome'];
  echo "<a href=\"show.php?id=".$id."\">".$nome."</a><br />";
}
?>
Naturalmente, la nostra prima operazione sarà quella di includere il file di configurazione contenente i parametri necessari per la connessione al DBMS e alla selezione del nostro database.

In secondo luogo, verrà operata una query di selezione con la quale estrarremo l’Id e il nome di ogni binario inserito in tabella.

L’ordine della selezione, è stato imposto per comodità espositiva in senso decrescente (DESC) rispetto all’autoincrementale, in ogni caso, nulla vieta al lettore di modificare la logica dell’interrogazione ordinando i dati secondo una campo differente (ad esempio il nome del file), oppure di imporre un limite al numero dei record estratti tramite la calusola LIMIT.

Una volta effettuata l’interrogazione, verranno elencati i link ad ogni immagine, il file destinato alla loro visualizzazione (show.php) raccoglierà da una querystring l’Id inviato tramite link.php in modo da mostrare l’immagine corrispondente ad esso.

5. Visualizzare file da una tabella MySQL

Passiamo ora all’ultima parte del nostro discorso riguardante la gestione delle immagini con PHP e MYSQL; ci accingiamo a creare una pagina attraverso la quale visualizzare le immagini contenute nel nostro database.

<?
if (isset($_GET['id']))
{
  $id = @intval($_GET['id']);
  @include 'config.php';
  $sql = "SELECT id,type,immagine FROM immagini WHERE id='$id'";
  $result = @mysql_query($sql) or die(mysql_error ());
  $row = @mysql_fetch_array($result);
  $id_img = $row['id'];
  $type = $row['type'];
  $img = $row['immagine'];
  if (!$id_img)
  {
    echo "Id sconosciuto";
  }else{
    @header ("Content-type: ".$type);
    echo $img;
  }
}else{
  echo "Impossibile soddisfare la richiesta.";
}
?>
Innanzitutto lo script controlla l’invio dell’Id da parte della pagina/elenco e solo se questo è stato raccolto dà vita al processo di visulizzazione.

Nel corso del listato vengono effettuati altri due controlli: il primo verifica l’Id attraverso la funzione intval() che estrae il valore intero da una variabile; il secondo convalida l’Id inviato, non sarà quindi possibile inviare alla query Id non registrati in tabella.

Una volta effettuati i controlli previsti, lo script esegue un’interrogazione al database sulla tabella delle immagini richiedendo l’estrazione dei dati relativi all’Id inviato in querystring tramite il metodo GET; quindi si procede alla stampa a video del file richiesto.

Da notare come la soddisfazione della rchiesta di visualizzazione necessiti che venga specificato nell’Header dell’output il Content-type relativo alla tipologia di immagine che vogliamo mostrare; per fare un esempio, un’immagine JPEG sarà specificata da un Content-type sul modello del seguente:

Content-type: image/jpeg

Altri contenuti interessanti

Pubblicità
Claudio Garau
Claudio Garau
Web developer, programmatore, Database Administrator, Linux Admin, docente e copywriter specializzato in contenuti sulle tecnologie orientate a Web, mobile, Cybersecurity e Digital Marketing per sviluppatori, PA e imprese.

Leggi anche...

Cannot modify header information – headers already sent: come risolvere l’errore PHP

L'errore di PHP cannot modify header information - headers...

Ricavare l’estensione di un file con PHP

Quando si lavora con i file in un'applicazione web,...

GD Library: creazione, manipolazione e ridimensionamento immagini con PHP

Le librerie GD (o GD Library), sono componenti fondamentali...

PHP: impostare il fuso orario italiano

Le tue pagine PHP non mostrano l’orario corretto? Probabilmente...

5 script PHP per gestire BBCode

A volte può aversi l'esigenza di dover offrire agli...
Pubblicità