Foros del Web » Programando para Internet » PHP »

Uso de imagenes BLOB, de forma dinámica en PHP

Estas en el tema de Uso de imagenes BLOB, de forma dinámica en PHP en el foro de PHP en Foros del Web. Hola, ¿Me gustaría saber cuál es la forma correcta de trabajar con imágenes almacenadas en base de datos, cuando estas son cargadas de forma dinámica? ...
  #1 (permalink)  
Antiguo 01/08/2011, 09:51
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Uso de imagenes BLOB, de forma dinámica en PHP

Hola,

¿Me gustaría saber cuál es la forma correcta de trabajar con imágenes almacenadas en base de datos, cuando estas son cargadas de forma dinámica?

Les pongo un ejemplo para que me entiendan. Supongamos que estamos desarrollando un catálogo de productos. La página será siempre la misma para todos los productos: "producto.php". Lo que cambia es que por parámetro recibe el id del producto: "producto.php?id=23". Entonces las imágenes que cargue, serán dependientes de dicho id.

Ahora, supongamos que con una consulta a Base de Datos, cargamos la información del producto: nombre, descripción, foto (BLOB), etc, etc. El archivo de la foto, es subido, mediante un panel administrativo, por otro usuario y puede ser jpg, png, etc. Lo que pensé es que mediante fwrite escribo el binario recibido en un archivo, con una extension "tonta" (por las diferentes extensiones) y agregar esta extensión al apache para que sea tratada como imagen por el navegador.

Mi idea inicial era tener un archivo "tonto" para cada una de las imágenes en pantalla, en el cual cargo el BLOB y muestro la imagen. El problema es que si dos personas están viendo la página "producto.php" al mismo tiempo, pero con ids distintos, puede que la ejecución de "persona 2" sobre-escriba la información de la imagen "img001" antes de que el navegador de "persona 1" cargue la imagen, en este caso cargando la imagen incorrecta.

Pensé dinámicamente crear un archivo en la carpeta de sesión, pero no se encuentra dentro del dominio de archivos públicos, por razones obvias. Otras soluciones, como la típica de realizar la consulta a base de datos en un archivo "file.php" al que se le modifica el header, no me gusta mucho, ya que estoy trabajando PHP por Objetos y se supone que el objeto "Producto" de donde tomo la información para la página, ya contiene todos los datos que se necesitan: Producto->getNombre(), fwrite($file, Producto->getImagen()).

La idea es que las imágenes sean creadas dinámicamente, para evitar tener un montón de archivos en el servidor y no tener que preocuparme por borrarlas cuando se elimine un item.

Saludos y gracias,
  #2 (permalink)  
Antiguo 01/08/2011, 09:54
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Tienes que almacenar si o si en la base de datos las imágenes con BLOB? Porque a mí me parece un atraso.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #3 (permalink)  
Antiguo 01/08/2011, 10:14
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Siempre he trabajado guardando los archivos físicos en el servidor. Pero deseo dar el paso para empezar a trabajar con BLOB, ya que a nivel de desarrollo, me parece más práctico trabajar así, porque, digamos que un usuario sube mediante el módulo administrativo una imagen, pero se da un error el guardar en la base de datos, entonces se realiza un rollback de mysql y tendría que realizar toda la lógica para eliminar del servidor la foto recientemente subida. Otra opción es subir la imagen después de guardada la información en la base de datos, pero qué pasa si hay un error al subir la imagen??.

La lógica actual que utilizo es:

if(subirImagen()){
if(guardarBD()){
commit()
}
else{
rollback()
borrarImagen()
}
}

Obviamente eso es a grandes rasgos, pero precisamente quiero evitar todo ese enredo (pensemos cuando el usuario administrador elimine una imagen). Si lo guardo en base de datos, al hacer commit o roll back, la imagen quedará almacenada o no.

Saludos y gracias,
  #4 (permalink)  
Antiguo 02/08/2011, 01:17
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Creo que no estás entendiendo la lógica de subir imágenes al servidor.

Cuando usas esto, lo que almacenas en la base de datos es la ruta de la imagen o, simplemente, el nombre con el que se ha almacenado y la ruta la construyes según en qué página la quieras imprimir. Y no hay que hacer ningún tipo de lógica para eliminarla si ha habido error, lo único que tienes que hacer es un buen control de errores. La idea es la siguiente:
Código PHP:
if (existe imagen en formulario) {
    if (
copiar la imagen a mi carpeta de servidor) {
        
/* si entra aquí todo ha ido bien */
        
crear el registro en la base de datos con la imagen
    
} else {
        
/* si entra aquí es que ha habido algún error */
        
control de error
    
}

El control de error puede ser el que tú quieras, por ejemplo, se puede añadir una imagen de error, creada por ti mismo e insertar el registro dirigiendo a esa imagen de error. Con esto solucionamos tu primer error.

Para el segundo error, en el caso de que la imagen se suba y no se cree el registro o en el caso de que el usuario elimine la imagen y se quede sin referencia. Es tan fácil como crearte un script que se ejecute cada cierto tiempo, que pegue un repaso a la carpeta de imágenes y borre aquellas imágenes que no tienen ningún registro asociado. No es un script difícil, de hecho, es bastante sencillo.

Espero que te ayuden mis consejos, quería insistir sobre todo en que no es necesario guardar en BLOB, pero si insistes en hacerlo así, puedes abrir otro post con dudas concretas, ya que aquí igual no te contestan más por mi culpa.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #5 (permalink)  
Antiguo 03/08/2011, 09:23
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Hola vgonga1986, gracias por tu interés.

Hace poco trabajé en un sitio bastante grande, lleno de imágenes por todo lado y que trabaja de la forma en la que me indicas, con las rutas de la imágenes. Bueno, con excepción de que no es un script el que periódicamente borra las imágenes, si no que es en el momento del control de errores.

Ese sitio en específico cuenta con más de 100 tablas, donde por lo menos un 40% cuenta con referencias a imágenes. Debes imaginarte lo pesado que debe ser realizar un script que tome en cuenta esa cantidad de tablas.

El asunto es que dentro de unas semanas empezaré a trabajar en un sitio más grande que ese, lleno de imágenes, mapas, flash y videos (mi jefes son diseñadores, y por lo visto les encantan lo sitios tan visuales) y todo esto será subido desde un módulo administrativo que será creado para el sitio, ya que es la forma en la que se trabaja en la empresa donde laboro.

Tal como dije al principio, agradezco la atención, pero si me gustaría empezar a trabajar con BLOB.

Saludos y gracias,
  #6 (permalink)  
Antiguo 03/08/2011, 09:51
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Buenas,

Siempre intento dar la opción más sencilla para la gente que llega, porque suelen venir despistados, pero veo que tú si que tienes tus requisitos y no puedes adaptarlo. Te recomiendo que abras otro post, porque aquí nadie te va a contestar viendo que ya yo te he ido contestando. Abre uno nuevo he indica claramente que tienes que trabajar con BLOB porque son requisitos de tu proyecto. Ahí alguien que controlo más (yo realmente no entiendo mucho) te echará una mano.

Un saludo y siento no haberte sido de ayuda.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #7 (permalink)  
Antiguo 03/08/2011, 10:31
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

De todas formas se agradece, saludos,
  #8 (permalink)  
Antiguo 03/08/2011, 10:39
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

No es necesario hacer otro post, para ver la imagen en BLOB es muy simple, solamente debes de imprimir la imagen en un contexto binario.

Siguiendo el ejemplo que dices producto.php, recibes por ID el id del producto, y dentro consultas los datos e imprimes la imagen así:
Código PHP:
Ver original
  1. <img src="fotoProducto.php?id=<?php echo $productoId; ?>"/>

Dentro de fotoProducto lo que haces es consultar a la bdd, y seleccionas el campo de imagen e imprimes las cabeceras, por ejemplo:
Código PHP:
Ver original
  1. <?php
  2. $id = $_GET['id'];
  3. // seleccionas etc
  4. $query = "SELECT foto FROM productos WHERE producto_id=$id";
  5. mysql_query($query);
  6. $row = mysql_fetch_array($query);
  7. header ('Content-type: image/jpg');
  8. echo $row['foto'];

Ten en cuenta que en ese script no puede tener nada más de texto, para que no te de un error de cabeceras, y es buena practica guardar junto con la imagen en BLOB, el tipo de imagen y el nombre original, así puedes descargar bien los datos, pe.
Código PHP:
Ver original
  1. header ('Content-type: ' . $row['type']);
  2. header ('Content-disposition: inline; filename=' . urlencode($row['name']));
  3.  
  4. echo $row['foto'];

Solo recuerda no imprimir nada antes ni después de tu foto en binario.

Saludos.
  #9 (permalink)  
Antiguo 03/08/2011, 11:22
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Hola GatorV, gracias por el interés.

Esa opción ya la había analizado, pero precisamente quiero evitar hacer la consulta en un archivo del tipo "fotoProducto.php", ya que trabajo orientado a objetos, por lo que tendría un objeto Producto que contiene los atributos (id, nombre, descripción, precio, foto) y la idea es cargar los datos del producto en una sola consulta (Producto->load(); => select * from productos where id = X).

Una vez cargados los datos, solo hago gets de los atributos.
Producto->getNombre();
Producto->getPrecio();
Y como lo mencioné en el primer post, dentro de las pruebas que hice y que me resultaron fue escribir de forma binaria un archivo vacío.
El código sería algo así:
$file = fopen('dummyFile_001.myext', 'wb');
fwrite($file, Producto->getFoto());
fclose($file);

En este caso, configuré apache para que tratara la extensión "myext" como archivo de imagen. Funciona bien, muestra la imagen. El problema se da porque si dos personas acceden a la misma página con un distinto idproducto, la foto será distinta, pero el archivo "dummyFile_001.myext" será el mismo, por ende si el "navegador1" no carga la foto antes de que "navegador2" realice la petición, "navegador1" mostrará "foto2", porque "navegador2" ya hizo la petición y el servidor re-escribió el contenido de "dummyFile_001.myext" con el contenido de "foto2".

Intentaré mostrarlo más claro. El ideal sería así:

1. navegador1 => peticion1
2. peticion1 => escribe contenido foto
3. navegador1 => muestra foto con contenido de peticion1
4. navegador2 => peticion2
5. peticion2 => escribe contenido foto
6. navegador2 => muestra foto con contenido de peticion2

Pero puede darse que:

1. navegador1 => peticion1
2. peticion1 => escribe contenido foto
3. navegador2 => peticion2
4. peticion2 => escribe contenido foto
5. navegador1 => muestra foto con contenido de peticion2 (incorrecto)
6. navegador2 => muestra foto con contenido de peticion2

No estoy seguro si hay forma de solucionar este problema de la forma en lo que yo quisiera, pero por eso consulto a ver si alguien si sabe.

Saludos y gracias,
  #10 (permalink)  
Antiguo 03/08/2011, 13:36
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Aunque trabajes de forma POO, es lo más recomendable, ya que de la forma que lo estas planteando te va a provocar el problema que tienes ahorita, y más ya que puede que se quede en cache la imagen y a la hora de ver otro producto veas la misma imagen. Aparte que el acceso a disco I/O es más costoso para escribir una imagen que ya tienes en binario.

Es mucho más barato a nivel memoria hacer la consulta extra para descargar la imagen a escribir en el archivo y presentarlo y luego borrarlo.

Otra opción que puedes hacer es tener tus imagenes en memoria y luego tener un cache de la imagen en disco, y tener un cron job que extraiga las imagenes de la BDD y las guarde en un lugar local cada X tiempo así las tienes en "respaldo".

Saludos.
  #11 (permalink)  
Antiguo 04/08/2011, 08:16
 
Fecha de Ingreso: julio-2010
Mensajes: 18
Antigüedad: 13 años, 9 meses
Puntos: 0
Respuesta: Uso de imagenes BLOB, de forma dinámica en PHP

Gracias GatorV.

Precisamente eso era lo que buscaba, una respuesta de cuál era la mejor forma de trabajar con imágenes BLOB. Es una lástima que no sea tan conveniente en la forma en la que me gustaría trabajar, pero si no es conveniente, pues no es conveniente.

Saludos y gracias,

Etiquetas: blob, imagenes, usuarios, formulario
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 08:57.