Salve, questo tutorial vi spiega come caricare un'immagine su di un database, o comunque qualsiasi altro tipo di file in formato binario senza salvarlo prima sul filesystem.

Non mi dilungo su come creare le tabelle del database, do solo come indicazione che il campo che deve contenere l'immagine dovrà essere almeno di tipo BLOG per un'immagine di circa 64Kbyte massimo, quindi meglio usare un MEDIUMBLOG che può contenere più di 16Mbyte.
Però attenzione perché comunque sono indicazioni di massima, dato che dipendono dal tipo di macchina dove è installato il database; infatti MySQL dice:
The maximum size of a BLOB or TEXT object is determined by its type, but the largest value you actually can transmit between the client and server is determined by the amount of available memory and the size of the communications buffers

La dimensione massima di un oggetto BLOB o TEXT è determinata dal suo tipo, ma il valore più grande è effettivamente possibile trasmettere tra il client e il server è determinata dalla quantità di memoria disponibile e la dimensione dei buffer di comunicazione
Quindi tutto dipende dalla vostra connessione e soprattutto dalle macchine di AV in questo caso vi consiglio di fare delle prove, se BLOG basta bene, se no passate ad un tipo superiore.

Detto ciò passo all'implementazione del codice!
Il file HTML che implementa il caricamente dell'immagine è semplice, tanto che prendo l'esempio del manuale del PHP:
Codice HTML:
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="upfile" type="file" />
    <input type="submit" value="Send File" />
</form>
Ognuno poi ha le sue idee su come formattarlo.

Quello che interessa invece è la parte PHP: come prendere il codice del file trasferito senza doverlo necessariamente salvare sul filesystem.
Quando inviate un file al server, sul PHP trovate l'array superglobale $_FILES che contiene tutto quello che avete inviato, esso consta di diverse parti, eccole:
  • name: porta il nome del file così come è stato trovato nel vostro hard disk;
  • type: il tipo mime del file caricato;
  • tmp_name: è il nome temporaneo univoco creato per distinguerlo in memoria da altri file simili ( ci importerà più tardi )
  • error: contiene un codice di errore;
  • size: la sua dimensione.

Quindi se vogliamo salvarlo in un databse procediamo così:
prima di tutto verifichiamo che non ci siano errori di caricamento, lascio a chi legge una eventuale verifica di altri errori:
Codice PHP:
try {
switch (
$_FILES['upfile']['error'] ) {
case
UPLOAD_ERR_OK:
break;
case
UPLOAD_ERR_NO_FILE:
throw new
RuntimeException( 'Nessun file è stato trasmesso.' );
break;
case
UPLOAD_ERR_INI_SIZE:
case
UPLOAD_ERR_FORM_SIZE:
throw new
RuntimeException( 'Eccede la dimensione massima del file.' );
break;
default:
throw new
RuntimeException( 'Errore sconosciuto.' );
}
}
catch (
Exception $e ) { echo $e->getMessage(); }
Se l'errore è zero, ovvero UPLOAD_ERR_OK lo script prosegue senza generare eccezioni.
Quindi sotto al ciclo switch prosegue in modo da verificare che il mime sia quello giusto:
Codice PHP:
if ( false === $ext = array_search(
$_FILES['upfile']['type'],
array (
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
),
true )
) {
throw new
RuntimeException( "Formato immagine non valido.\nO il file non è un'immagine." );
}
Chiaramente questa verifican on è il massimo della sicurezza, in realtà il type di $_FILES è alquanto superato in quanto a sicurezza perché non verifica affatto la corrispondenza tra ciò che c'è nel file e il suo tipo ma si limita a leggere il punto del file dov'è scritto il tipo, questo fa sì che è possibile trasferire anche un file eseguibile facendolo passare per qualcos'altro.
Persino Mime Content Type è deprecato.
Meglio sarebbe usare finfo(), non ho ancora verificato se AV lo supporta, ma di solito non esiste sui server perché complessa da installare.

Ora procediamo con il caricamento del file nel database:
Codice PHP:
/**
Assumo che sappiate come aprire e fare un INSERT o un UPDATE su MySQL quindi non mi dilungo,
dico solo che uso le estensioni PDO per l'esempio, quindi mettiamo caso che...
*/
$handle = $connessione->prepare( 'INSERT INTO immagini (immagine) VALUES (:img)' );
$immagine = file_get_contents( $_FILES['upfile']['tmp_name'] );
$handle->bindValue( ':img', $immagine );
$handle->execute();
unset(
$_FILES, $connessione, $handle, $immagine );
Tutto qui!
In pratica, fatti tutti i controlli di rito sull'array $_FILES tutto quello che dovrete fare è leggere la variavile $_FILES['upfile']['tmp_name'] considerandola a tutti gli effetti un file e trasferirne il contenuto nel campo BLOG del database, non importa il metodo che usiate.

Qui sotto il file PHP completo, chiamatelo come più vi piace oppure inseritelo in un vostro progetto più grande.
Codice PHP:
try {
switch (
$_FILES['upfile']['error'] ) {
case
UPLOAD_ERR_OK:
break;
case
UPLOAD_ERR_NO_FILE:
throw new
RuntimeException( 'Nessun file è stato trasmesso.' );
break;
case
UPLOAD_ERR_INI_SIZE:
case
UPLOAD_ERR_FORM_SIZE:
throw new
RuntimeException( 'Eccede la dimensione massima del file.' );
break;
default:
throw new
RuntimeException( 'Errore sconosciuto.' );
}
if (
false === $ext = array_search(
$_FILES['upfile']['type'],
array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
),
true )
) {
throw new
RuntimeException( "Formato immagine non valido.\nO il file non è un'immagine." );
}
$handle = $connessione->prepare( 'INSERT INTO immagini (immagine) VALUES (:img)' );
$immagine = file_get_contents( $_FILES['upfile']['tmp_name'] );
$handle->bindValue( ':img', $immagine );
$handle->execute();
unset(
$_FILES, $connessione, $handle, $immagine );
}
catch (
PDOException $e ) { echo 'Errore PDO: ' . $e->getMessage(); }
catch (
Exception $e ) { echo 'ERRORE GENERICO: ' . $e->getMessage(); }
Spero vi sia d'aiuto in qualche vostro progetto.

Ciao, M.