Cuando creamos un software o un sitio web que utiliza archivos, debemos decidir como almacenarlos, una de las posibilidades es crear una carpeta y almacenar allí los archivos y otra posibilidad es almacenarlos en la base de datos, debemos tener cuenta que un campo longblob puede almacenar hasta 4 gigabytes.
El motor de base de datos mySQL, permite utilizar campos bloque almacenan la información en formato binario. Este formato permite almacenar diversos tipos de archivos, como Word, Excel, cualquier tipo de imágenes, archivos pdf, etc. En este tutorial veremos cómo almacenar archivos en una tabla de una base de datos MySQL, los datos serán enviados desde un formulario html y procesados con PHP para guardar los archivos en la base de datos.
Para realizar los ejemplos del tutorial necesitaremos un servidor remoto o uno local que se pueden instalar como vimos en el tutorial:
- Como Instalarte Xampp para convertir tu ordenador en un servidor web, de esta manera tendremos soporte para php y mysql y todas las librerías necesarias.
A continuación crearemos la base de datos que almacenará datos de vehículos, con foto y ficha técnica en pdf, para ello crearemos desde phpmyadmin el ejemplo que se denominará concesionario. A continuación crearemos la tabla autos.
CREATE DATABASE concesionario; Estructura de tabla para la tabla `autos` CREATE TABLE `autos` ( `id` int(11) NOT NULL, `marca` varchar(150) DEFAULT '0', `modelo` varchar(150) DEFAULT '0', `foto` longblob ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Indices de la tabla `autos` ALTER TABLE `autos` ADD PRIMARY KEY (`id`); AUTO_INCREMENT de las tablas volcadas AUTO_INCREMENT de la tabla `autos` ALTER TABLE `autos` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;Código de creación de tabla
A continuación crearemos un archivo config.php desde donde nos conectaremos a la base de datos:
<? // conectar al servidor mysql $link = mysql_connect('localhost', 'root', ''); if (!$link) { die('Error de conexion a mysql : ' . mysql_error()); } //conectar a la base de datos if (! mysql_select_db('concesionario') ) { die ('error de conexión base de datos : ' . mysql_error()); } ?>Config.php
A continuación vamos a crear una pagina en PHP que se encargará de listar todos los registros de la tabla autos.
<? error_reporting(0); include('config.php'); ?> <style> table { font: 14px Arial; border: 1px solid #CCCCCC; margin-bottom:10px; } td { width:100px; } a.boton { font: bold 14px Arial; text-decoration: none; background-color: #EEEEEE; color: #333333; padding: 2px 6px 2px 6px; border: 1px solid #CCCCCC; } </style> <? echo "<table border=1 cellspacing=0 >"; echo "<tr>"; echo "<td><b>Marca</b></td>"; echo "<td><b>Modelo</b></td>"; echo "<td><b>Foto</b></td>"; echo "<td colspan=2><b>Acciones</b></td>"; echo "</tr>"; $resultado = mysql_query("SELECT * FROM `autos`") or trigger_error(mysql_error()); while($filas = mysql_fetch_array($resultado)){ foreach($filas AS $clave => $valor) { $filas[$key] = stripslashes($value); } echo "<tr>"; echo "<td valign='top'>" . $filas['marca'] . "</td>"; echo "<td valign='top'>" . $filas['modelo'] . "</td>"; echo "<td valign='top'><a href='verfoto.php?id=" . $filas['id'] . "'> Ver Foto</a></td>"; echo "<td valign='top'><a href=editar.php?id={$filas['id']}>Editar</a></td> <td><a href=eliminar.php?id={$filas['id']}>Eliminar</a></td> "; echo "</tr>"; } echo "</table>"; echo "<a href=alta.php class='boton'>Nuevo auto</a>"; ?>Listar todos los registros de la tabla
El formulario para dar de alta los datos que nos permita dar de alta una foto, para ello deberemos usar elementos file que nos permita seleccionar un archivo desde el navegador para y luego procesarlo con PHP y guardar los datos en los campos blob de nuestra tabla autos de la base de datos.
Creamos la web dentro de una carpeta denominada concesionario en nuestro servidor. La página web contendrá el código HTML y PHP, en el formulario deberemos utilizar el atributo enctype="multipart/form-data" que indica que se puede enviar archivos a través del formulario, si no tiene el atributo no se podrán enviar archivos.
Esta pagina se denominará alta.php
El código es el siguiente:
<? error_reporting(0); include('config.php'); if (isset($_POST['enviado'])) { foreach($_POST AS $key => $value) { $_POST[$key] = mysql_real_escape_string($value); } // leemos datos de la foto $foto= $_FILES["foto"]["tmp_name"]; $nombrefoto = $_FILES["foto"]["name"]; //este es el archivo que añadiremosal campo blob $foto = $_FILES['foto']['tmp_name']; //lo comvertimos en binario antes de guardarlo $foto=mysql_real_escape_string(file_get_contents($_FILES["foto"]["tmp_name"])); $sql = "INSERT INTO `autos` ( `marca` , `modelo` , `foto` ) VALUES( '{$_POST['marca']}' , '{$_POST['modelo']}' , '$foto' ) "; mysql_query($sql) or die(mysql_error()); header('Location: listautos.php'); } ?> <form enctype="multipart/form-data" action="alta.php" method="POST"> <p><b>Marca:</b><br /><input type='text' name='marca'/> <p><b>Modelo:</b><br /><input type='text' name='modelo'/> <p><b>Foto:</b><br /><input name="foto" type="file" /> <p><input type='submit' value='Guardar' /> <input type='hidden' value='1' name='enviado' /> </form>A continuación deberemos mostrarlo para ello crearemos una pagina que interprete el archivo binario y lo muestre, crearemos la pagina verfoto.php y le indicaremos el id de la foto a mostrar.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Documento sin título</title> </head> <body> <?php include('config.php'); $sql= "SELECT foto FROM autos where id=".$_GET['id']; $resultado= mysql_query($sql); $filas= mysql_fetch_assoc($resultado); //Mostramos la imagen en este formato solo mostramos imagenes png //Si necesitamos cambiar la extension haremos un if condicional //para cada extension soportada gif,jpg, etc ?> <img src="data:image/png;base64,<?php echo base64_encode($filas['foto']); ?>" alt="titulo foto" /> </body> </html> </html>
Podemos además extraer los atributos del archivo si lo necesitamos de la siguiente manera:
<? $nombrefoto=$_FILES[foto]['name'] $extensionfoto=$_FILES[foto]['type'] //Tipo de archivo image/png, application/pdf, etc $tamanofotobytes=$_FILES['archivito']['size'] //Tamaño en bytes $nombrearchivo=$_FILES['archivito']['tmp_name'] ?>El archivo se almacena en la memoria en forma temporal durante el proceso, si ocurre algún error los datos pueden perderse o no grabarse completos, el script PHP elimina el archivo temporal de la memoria después de finalizado el proceso, aunque este no finalice correctamente.
A continuación crearemos la pagina para editar los datos de un auto, que denominaremos editar.php
<? include('config.php'); if (isset($_GET['id']) ) { $id = (int) $_GET['id']; if (isset($_POST['enviado'])) { foreach($_POST AS $clave => $value) { $_POST[$clave] = mysql_real_escape_string($valor); } // leemos datos de la foto $foto= $_FILES["foto"]["tmp_name"]; $nombrefoto = $_FILES["foto"]["name"]; //este es el archivo temporal $foto = $_FILES['foto']['tmp_name']; //leer el archivo temporal en binario $foto=mysql_real_escape_string(file_get_contents($_FILES["foto"]["tmp_name"])); $sql = "UPDATE `autos` SET `marca` = '{$_POST['marca']}' , `modelo` = '{$_POST['modelo']}' , `foto` = '$foto' WHERE `id` = '$id' "; mysql_query($sql) or die(mysql_error()); header('Location: listautos.php'); } $filas = mysql_fetch_array ( mysql_query("SELECT * FROM `autos` WHERE `id` = '$id' ")); ?> <form action='' method='POST'> <p><b>Marca:</b><br /><input type='text' name='marca' valor='<?= $filas['marca'] ?>' /> <p><b>Modelo:</b><br /><input type='text' name='modelo' valor='<?= $filas['modelo'] ?>' /> <p><b>Modelo:</b><br /><input type='text' name='modelo'/> <p><b>Foto:</b><br /><input name="foto" type="file" /> <p><input type='submit' value='Guardar' />> <input type='hidden' value='1' name='enviado' /> </form> <? } ?>Debemos tener en cuenta que si eliminamos un registro eliminaremos los archivos al mismo tiempo y no podrán ser recuperados. Para eliminar un registro crearemos la pagina eliminar.php y utilizaremos el siguiente código.
<? include('config.php'); $id = (int) $_GET['id']; mysql_query("DELETE FROM `autos` WHERE `id` = '$id' ") ; header('Location: listautos.php'); ?>Hemos realizado un código simple sin mucho diseño para explicar como almacenar archivos en campos blob, una de las desventajas es que el tamaño de la base de datos crece mucho al almacenar archivos en formato binario.
Una de las ventajas es que los archivos se guardan dentro de una tabla, lo que es mejor por el tema de la seguridad, ya que sólo se podrá acceder a los archivos si se tiene los permisos para gestionar la base de datos y no existe una carpeta física de donde descargarse los archivos o manipularlos por parte de un atacante.