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.

Pubblicitร 

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ร 

Potrebbero interessarti queste guide

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...

PHP BBCode: script pronti allโ€™uso

A volte puรฒ aversi l'esigenza di dover offrire agli...
Pubblicitร