[Ir al menú de PHP]
Guardar y leer imágenes en tablas

Peculiaridades de las tablas

Las tablas que han de contener imágenes deben tener campos del tipo BLOB, MEDIUMBLOB o LONGBLOB dependiendo de los tamaños de las mismas y limitados por las especificaciones del servidor MySQL.

Por si te has olvidado de los tipos de campos, aquí tienes un enlace para recordarlos. De nada ;-)

En el ejemplo la hemos creado con un campo BLOB insertando también campos para recoger su nombre, su tamaño (expresado en bytes), su formato (el tipo de fichero transferido) así como un campo autoincremental.

Transferencia de la imagen

El formulario para realizar la transferencia de la imagen no tiene particularidades. Es un formulario como los de toda la vida. Lo único reseñable sería incluir un campo oculto en el que pudiera especificarse una rectricción en cuanto al tamaño máximo permitido para cada imagen.

Comprobación
del tipo de imagen

Se me ocurrió pensar en la posibilidad de incluir un filtro que restringiera los formatos de los ficheros transferidos. Uno nunca sabe que le puede regalar y para evitar que alguien pudiera obsequiarnos con algo raro (estoy seguro de que no serían euros).

Aquí tropecé con un problemilla.

Desde que alguien me riñó –me llamo de todo menos guapo, menos mal ;-)- por mofarme (sospecho que mi humor ni ironía figuran en su vocabulario) de cualquier navegador que no sea IE vivo obsesionado (¿será un trauma de infancia?) con la famosa compatibilidad de navegadores. Señores de Hacienda. Les juro que no estoy subvencionado por Bill Gates. ¡Creáme!. Ya me gustaría... pero no... no debo de estar en la lista de protocolo de Microsoft.

A lo que íbamos. Cuando intenté transferir imágenes jpg me di cuenta de que dependiendo de navegador que usara el type MIME que recibía el servidor era distinto. Igual ocurría cuando se trataba de png.

Por eso tuve que recurrir a la chapucilla que te comento en el ejemplo de la derecha. Cosas de la vida ;-)

Observé también otra cosa interesante. Cuando Apache lee las imágenes desde un fichero le basta con un tipo MIME único y que todos los navegadores visualizan la imagen como benditos. Esa es la razón por la que guardo en la tabla del ejemplo los tipos de extensión que contiene la variable del mismo nombre.

¿Cómo guardamos la imagen?

La información recibida en el servidor -a través del formulario- requiere un ligero maquillaje antes de incluirla en le campo BLOB de la tabla. Esa reconversión requiere abrir la imagen en modo binario -parece que solo en el caso de Windows– leer el fichero completo y añadirle las famosas \ antes de las comillas, etc. etc.

Una vez maquillada ya puede guardarse sin más problema. ¡Cosas de la estética!.

Se me olvidaba... -esta memoria me está fallando- en el campo formato no basta con poner jpg, png, etc. Hay que poner el tipo MIME y eso lo he resuelto usando la famosa variable extensión.

Ver las imágenes

Parecía que eso estaba chupao pero, mira por dónde, tuve que recurrir al acetilsalicílico.

Traté de leer todas la imágenes de la tabla de una sola vez... y el fracaso fué estrepitoso. Y lo fué por culpa de dichoso header. La lectura de una imagen utiliza solo dos instrucciones. El dichoso header en el que se indica el tipo de contenido (el famoso nombre MIME de la imagen) y luego imprimir el contenido del campo. Pero... por aquello de que header debe ir incluida en el script antes que cualquier otra salida tuve que recurrir a la chapucilla que ves en los ejemplos.

Leer la tabla de las afotos para extraer los campos informativos y a la hora de ver el asemeyu (así decía mi madre a las fotos) recurrir a la misma técnica que utilizaba para ver las imagenes dinámicas.

Es decir, poner una etiqueta de imagen de las de HTML de toda la vida pero -en vez de escribir el nombre de la imagen- poniendo el nombre del script que lee los asemeyos y pasándole el número de la imagen que pretendí visualizar.

¿Y ... andó?

Bueno... me pasó como en el chiste de Lázaro... Andar si que andó con un solo pero no imputable a PHP sino a la compatiblidad de los distintos navegadores.

Se trata de los png con transparencias. En IE se repite el problema típico del fondo gris, en Mozilla y Firefox no hay problema. Prueba con el ejemplo y podrás comprobarlo.

 
 


Creación de una tabla ejemplo

Lo primero de todo será disponer de una tabla en la que puedan guardarse imágenes. Aquí tienes un ejemplo.


<?
#el nombre de la tabla
$base="rinconastur";
#definimos otra variable con el NOMBRE QUE QUEREMOS DAR A LA TABLA
$tabla="fotos";
# establecemos la conexión con el servidor
$conexion=mysql_connect ("localhost","pepe","pepa");
#Seleccionamos la BASE DE DATOS en la que PRETENDEMOS CREAR LA TABLA
mysql_select_db ($base, $conexion);

$crear="CREATE TABLE IF NOT EXISTS $tabla (";
$crear.="num_ident INT(10) unsigned NOT NULL AUTO_INCREMENT,";
$crear.="imagen BLOB NOT NULL, ";
$crear.="nombre VARCHAR(255) NOT NULL DEFAULT '',";
$crear.="tamano VARCHAR(15) NOT NULL DEFAULT  '',";
$crear.="formato VARCHAR(10) NOT NULL DEFAULT  '',";
$crear.="PRIMARY KEY (num_ident))";

#Creamos la cadena, comprobamos si esa instrucción devuelve
# VERDADERO o FALSO
# y dependiendo de ellos insertamos el mensaje de exito o fracaso

if(mysql_db_query ($base,$crear ,$conexion)) {
echo "<h2> Tabla $tabla creada con EXITO </h2><br>";
    }else{
echo "<h2> La tabla $tabla NO HA PODIDO CREARSE</h2><br>";
};

# cerramos la conexión... y listo...

        mysql_close($conexion);
?>

Formulario para la transferencia de las imágenes


<FORM ENCTYPE="multipart/form-data" ACTION="g_fotos.php" METHOD="post">
#con este input "oculto" establecemos el limite máximo
# del tamaño del fichero a transferir. En este ejemplo 65.000 bytes
<INPUT type="hidden" name="lim_tamano" value="65000">
<p><b>Selecciona la imagen a transferir<b><br>
<INPUT type="file" name="foto"><br>
<p><b>Título la imagen<b><br>
<INPUT type="text" name="titulo"><br></p>
<p><INPUT type="submit" name="enviar" value="Aceptar"></p>
</FORM>

Script para actualizar la base de datos


<?
$foto_name= $_FILES['foto']['name'];
$foto_size= $_FILES['foto']['size'];
$foto_type=  $_FILES['foto']['type'];
$foto_temporal= $_FILES['foto']['tmp_name'];
$lim_tamano= $_POST['lim_tamano'];
$foto_titulo= $_POST['titulo'];
/* limitamos los formatos de imagen admitidos a:
    png  que segun del navegador que ulicemos puede ser:
   en IE image/x-png  en Firefox y Mozilla image/png
   jpg que puede tener como tipo
   en IE image/pjpeg  en Firefox y Mozilla image/jpeg
   gif que tiene como tipo image/gif en todos los navegadores
    Mira los comentarios al margen sobre la variable $extensión */
if ($foto_type=="image/x-png" OR $foto_type=="image/png"){
 $extension="image/png";
 }
if ($foto_type=="image/pjpeg" OR $foto_type=="image/jpeg"){
 $extension="image/jpeg";
 }
if ($foto_type=="image/gif" OR $foto_type=="image/gif"){
 $extension="image/gif";
 }
# condicionamos la inserción a que la foto tenga nombre,
# un tamaño distinto de cero y menor de límite establecido
# en el formulario y que la variable extensión sea no nula

if ($foto_name != "" AND $foto_size != 0
                           AND $foto_titulo !='' AND
                        $foto_size<=$lim_tamano AND $extension !=''){
/*reconversion de la imagen para meter en la tabla
 abrimos el fichero temporal en modo
 lectura "r" binaria"b"*/
$f1= fopen($foto_temporal,"rb");
#leemos el fichero completo limitando
#  la lectura al tamaño de fichero		
$foto_reconvertida = fread($f1, $foto_size);
#anteponemos \ a las comillas que pudiera contener el fichero
# para evitar que sean interpretadas como final de cadena	
$foto_reconvertida=addslashes($foto_reconvertida);
# abrimos la base de datos y escribimos las intrucciones de inserción
# en el campo BLOB insertaremos la foto_reconvertida
$base="rinconastur";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
$meter="INSERT INTO ".$tabla;
$meter .=" (num_ident, imagen, nombre, tamano, formato) ";
$meter .=" VALUES('','$foto_reconvertida','$foto_titulo',";
$meter .= "$foto_size, '$extension')";
    if (@mysql_query($meter,$conexion)){
        print "Foto guardada en la tabla";
        }else{
        print "Ha habido un error al guardar la foto";
    }
}else{
    echo "<h2>No ha podido transferirse el fichero</h2>";
 }
 mysql_close();
?>

Script para leer la base de datos


<?
$base="rinconastur";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
    $sacar = "SELECT * FROM ".$tabla;
    $resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
  print "<center>Titulo de la imagen: ".$registro['nombre']."<br>";
  print "<img src='ver_foto.php?n=".$registro['num_ident']."'><br>";
  print "Tamaño de la imagen: ".$registro['tamano']." bytes
</center>"; } mysql_close(); ?>

Script para leer imágenes de la base datos


<?
$numero=$_REQUEST['n'];
$base="rinconastur";
$tabla="fotos";
$conexion=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $conexion);
    $sacar = "SELECT * FROM ".$tabla." WHERE (num_ident=$numero)" ;
    $resultado = mysql_query($sacar,$conexion);
while ($registro = mysql_fetch_array($resultado)){
            $tipo_foto=$registro['formato'];
             header("Content-type: $tipo_foto");
             echo $registro['imagen'];
}
mysql_close();
?>


Ver imágenes guardadas en una tabla MySQL


Sugerir a un/a amig@ Envíame tus comentarios
Anterior
Indice
Siguiente