L'estensione mysqli - III

Gestione dei BLOB

Come accadeva per la vecchia ext/mysql, la gestione dei dati di tipo BLOB (Binary Large OBject) è analoga a quella dei dati normali. ext/mysqli in più introduce una nuova modalità di inserimento dei dati BLOB di gran lunga più efficiente. Attraverso l'uso del metodo send_long_data() della classe mysqli_stmt i voluminosi dati binari non devono essere contenuti nella query ed inviati tutti insieme ma, sfruttando il binding dei parametri, possono essere inviati al server MySQL un po' per volta.

L'esempio che proponiamo è una rivisitazione dello script proposto per l'upload e l'inserimento dei files all'interno di un database MySQL. Questa volta useremo le classi messe a disposizione da ext/mysqli ed in particolare vedremo come impiegare il metodo send_long_data().

 

<?php
// se è stato inviato il file...
if(isset($_POST['invia']))
{
	// se ci sono stati problemi nell'upload del file
	if(!isset($_FILES['file_inviato']) OR $_FILES['file_inviato']['error'] != UPLOAD_ERR_OK)
	mostra_form("errore nell'invio del file. Riprova");

	// connessione e selezione del database
	$mysqli = new mysqli('localhost', 'root', 'password_db', 'test');

	// recupero alcune informazioni sul file inviato
	$nome_file_temporaneo = $_FILES['file_inviato']['tmp_name'];
	$nome_file_vero = $_FILES['file_inviato']['name'];
	$tipo_file = $_FILES['file_inviato']['type'];


	// preparo la query per inserire i dati nel DB
	$stmt = $mysqli->prepare("INSERT INTO tabella_files VALUES (NULL, ?, ?, ?)");

	// collego i parametri della query alle variabili PHP
	$stmt->bind_param('ssb', $nome_file_vero, $tipo_file, $dati_file);

	// apro il file in lettura
	$fp = fopen($nome_file_temporaneo,"rb");
	while ($dati_file = fread($fp,1024))
	{
		$stmt->send_long_data(2, $dati_file);
	}

	if ($stmt->execute())
	{
		$messaggio = "Memorizzazione del file <b>$nome_file_vero</b> nel database eseguita correttamente.";
	}
	else
	{
		$messaggio = "Errore nella memorizzazione del file <b>$nome_file_vero</b>";
	}

	// mostro nuovamente il form ed un messaggio di successo
	mostra_form("Memorizzazione del file <b>$nome_file_vero</b> nel database eseguita correttamente.");
}
else
{
	mostra_form();
}

/**
* Mostra il form per l'upload del file
*
*/
function mostra_form($messaggio = '')
{
	echo <<<END
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Carica file nel database</title>
</head>
<body>
	<p>$messaggio<br>Seleziona un file da memorizzare nel database: </p>
	<form name="form1" enctype="multipart/form-data" method="post" action="">
		<p>
			<input type="file" name="file_inviato">
		</p>
		<p>
			<input type="submit" name="invia" value="Invia file">
		</p>
	</form>
</body>
</html>
END;
exit();
}
?>

Il punto di forza di questa tecnica consiste nell'accoppiata della funzione fread() con il metodo send_long_data(). fread() infatti legge di volta in vola solo parte del file, send_long_data() a sua volta prende questi frammenti e li invia a MySQL.

Lo script PHP quindi non dovrà tenere in memoria tutto il file, inoltre l'invio graduale dei dati non rischierà di far superare le dimensioni imposte dalla direttiva max_allowed_packet del server MySQL, ovvero la massima dimensione che può raggiungere una query. Si noti infine come sia comunque necessario richiamare il metodo execute() della classe mysqli_stmt per eseguire realmente la query.

Pagine: precedente 1 2 3 4 5
Effettua l'accesso o registrati per inserire un commento