Il modo maggiormente utilizzato per la gestione dei files, in particolare di tipo immagine, con l'uso di un database è quello di memorizzare in un campo di una tabella il solo percorso dell'immagine interessata per poi richiamare, tramite questo path appunto, il file memorizzato sul server in una directory dedicata. Questo sistema offre numerosi vantaggi, sia dal punto di vista pratico che sotto l'aspetto relativo alle dimensioni del database, in quanto il file non viene memorizzato fisicamente all'interno del database ma se ne registra solo il path.
Potrebbe capitare però di avere la necessità, per svariati motivi, di archiviare le immagini direttamente nel database. Una delle caratteristiche fondamentali fra il sistema illustrato precedentemente e quest'ultimo è costituita dal diverso tipo di campo che servirà ad accogliere i file. Nel primo caso si avrà, ad esempio, un semplice campo di tipo VARCHAR(n) mentre nel secondo avremo bisogno del tipo BLOB. Vi rimando alla sezione relativa del manuale per le caratteristiche. Per altre utili notizie sul tema, segnalo anche quest'ottimo articolo di gm.
Questo tutorial, pur non avendo la pretesa di soddisfare interamente l'argomento legato alla gestione di files memorizzati direttamente in database, si propone come obiettivo la realizzazione di un sistema per visualizzare le immagini memorizzate direttamente nel database.
Il progetto sarà composto da vari file, primo per gestire più agevolmente eventuali modifiche o aggiornamenti e secondo per un motivo essenziale nel creare il sistema di visualizzazione delle immagini: dividere le attività che lo script dovrà svolgere. Quest'ultimo fondamentale aspetto può essere spiegato in sintesi in questo modo: uno script non può creare un documento HTML e contemporaneamente rappresentare un'immagine, le due attività devono essere svolte da script diversi. Il primo script crea la pagina HTML, includendo il tag <img> per l'immagine. In questo tag non verrà indicato il percorso del file locale dell'immagine ma bensì il nome del secondo script PHP e il codice ID dell'immagine archiviata nel database.
Per chiarire meglio il concetto ho preparato del codice da esempio e per facilitare eventuali test ho riportato anche la struttura della tabella che servirà per memorizzare le immagini. Potreste copiare il codice SQL per la creazione della tabella in un file di testo e poi modificarne l'estensione in .sql per importarlo nel vostro database o più semplicemente usare direttamente il codice per lanciare una query col vostro programma di gestione database preferito. (Script testato con MySQL: 5.0.24)
create_table.sql
codice:
CREATE TABLE IF NOT EXISTS `image` (
`IDimg` mediumint(6) NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
`type` varchar(20) NOT NULL,
`alt` varchar(20) NOT NULL,
`title` varchar(40) NOT NULL,
`note` varchar(100) NOT NULL,
`image` mediumblob NOT NULL,
`ts` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`IDimg`)
) ENGINE=MyISAM;
Una volta creata la tabella possiamo passare alla realizzazione del file di configurazione che conterrà il solo codice per la connessione al database.
config.inc.php
Codice PHP:
<?php
$cfg['DBhost'] = 'localhost';
$cfg['DBuser'] = 'root';
$cfg['DBpass'] = '';
function connectDB($DBname)
{
global $cfg;
$DBlink = @mysql_connect($cfg['DBhost'], $cfg['DBuser'], $cfg['DBpass']) or die(mysql_error());
return !mysql_select_db($DBname) ? die(mysql_error()) : $DBlink;
}
?>
Il codice è semplicissimo, la funzione connectDB() richiede un solo parametro: il nome del database a cui connettersi. Vedremo adesso il primo script che si occuperà di recuperare le immagini archiviate nel database. Per praticità ho omesso le istruzioni per l'upload in quanto non strettamente necessarie per comprendere il funzionamento dello script. Ovviamente, nel realizzarne uno vostro dovrete tenere conto della struttura della tabella proposta in precedenza di modo da compilare esattamente tutti i campi necessari.
images.php
Codice PHP:
<?php
include('config.inc.php');
$DBlink = connectDB('images');
$sql = mysql_query("SELECT IDimg, alt, title FROM image") or die(mysql_error());
while($row = mysql_fetch_object($sql)) {
echo "<img src=\"img.php?ID=$row->IDimg\" alt=\"$row->alt\" title=\"$row->title\" /> ";
}
?>
Una breve spiegazione del codice. Abbiamo memorizzato la funzione per la connessione al database nella variabile $DBlink e quindi lanciato la query per recuperare i campi necessari per completare gli attributi del tag <img>. Poi scorriamo il risultato e quindi andiamo a creare il "richiamo" alla procedura del secondo script (img.php) con l'attributo src del tag <img>, grazie alla chiave inviata in query string: ID.
Adesso passiamo alla creazione dell'ultimo file, il più importante, che ci permetterò di visualizzare l'immagine.
img.php
Codice PHP:
<?php
include('config.inc.php');
$DBlink = connectDB('images');
$ID = isset($_GET['ID']) ? (int)$_GET['ID'] : exit(header('Location: images.php'));
$sql = mysql_query("SELECT type, image FROM image WHERE IDimg = $ID") or die(mysql_error());
$row = mysql_fetch_object($sql);
header("Content-type: $row->type");
echo $row->image;
?>
Ok, siamo alla fine. Il codice essenzialmente è molto simile a quello visto precedentemente.
Dopo la solita connessione al database "images" andiamo a recuperare il valore inviato tramite la chiave ID del codice <img> del file images.php, effettuando una serie di controlli. Verifichiamo se la chiave è realmente settata, in caso positivo facciamo il cast ad intero per evitare complicazioni con la query qualora non si trattasse di caratteri numerici. Altrimenti concludiamo l'esecuzione dello script e facciamo un redirect alla pagina images.php, anche nel caso il file img.php dovesse essere richiamato direttamente tramite la barra indirizzi del browser.
Successivamente andiamo a realizzare la query che si occuperà di recuperare il tipo, gif, png o jpeg, di immagine e il file immagine stesso tramite la variabile $ID che abbiamo usato prima. Infine, recuperati i dati esatti dal database, grazie all'uso di un'header specifichiamo il tipo di immagine e subito dopo richiamiamo il file vero e proprio.
Questo è quanto! La soluzione che ho cercato di proporre potrebbe stimolarvi per ulteriori approfondimenti sul tema. Allo stesso tempo sarebbe interessante magari ampliare il progetto con vostre integrazioni e aggiunte per migliorarne il funzionamento.