error al mostrar imagenes cargadas de una base de datos

1,566 views
Skip to first unread message

Andrés Oporto

unread,
Nov 3, 2015, 7:07:32 PM11/3/15
to Grupo PHP Argentina
Hola hice un programa en php que guarda dos valores cargados en un formulario, además de guardar una imagen, pero al querer verla no me aparece.
Me graba los datos bien, ademas los puedo ver, pero no me muestra la imagen.


tabla_db2.sql
CREATE TABLE IF NOT EXISTS `tabla_db2` (
 
`id` int(11) NOT NULL auto_increment,
 
`nombre` varchar(20) NOT NULL,
 
`email` varchar(50) NOT NULL,
 
`foto` mediumblob NOT NULL,
  PRIMARY KEY  
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;






index.php
<html>  

<head>  
<title>Guardar datos en una base de datos</title>  
</head>  

<body>

<?php

error_reporting
(0);

# Conectamos con MySQL

$link
=mysqli_connect("localhost","root","","prueba");

if (mysqli_connect_errno()) {

   
die("Error al conectar: ".mysqli_connect_error());

}
 
?>

<form enctype="multipart/form-data" action="
<?php echo $_SERVER["PHP_SELF"]?>" method="POST">    
   
<p>Nombre: <input type="text" name="nombre" size="20"></p>
   
<p>E-mail: <input type="text" name="email" size="20"></p>  
   
<input name="guarda" type="file">    
   
<p><input type="submit" value="Guardar datos" name="B1"></p>  
     
</form>  
   
<h2>Listado de las imagenes añadidas a la base de datos</h2>
   
     
<?php

    $result
=mysqli_query($link,"SELECT * FROM tabla_db2 ORDER BY id DESC");

   
if($result)

   
{

       
while($row=mysqli_fetch_array($result))

       
{
            echo
"<img src='imagen_mostrar.php?id=".$row["id"]."' nombre='".$row["nombre"]."' email='".$row["email"]."'>";
            echo
"<br>";
            echo
'id='.$row["id"];
            echo
"<br>";
            echo
'nombre='.$row["nombre"];
            echo
"<br>";
            echo
'email='.$row["email"];        
            echo
"<br>";            
       
}

   
}

   
?>
   
   
</body>  

</html>

<?php  

// Recibimos por POST los datos procedentes del formulario  


if (isset($_POST['nombre']))
{
    $nombre
= $_POST['nombre'];            
}
if (isset($_POST['email']))
{
    $email
= $_POST['email'];            
}  
 
if (is_uploaded_file($_FILES["guarda"]["tmp_name"]))

{

   
# verificamos el formato de la imagen

   
if ($_FILES["guarda"]["type"]=="image/jpeg" || $_FILES["guarda"]["type"]=="image/jpg" || $_FILES["guarda"]["type"]=="image/gif" || $_FILES["guarda"]["type"]=="image/bmp" || $_FILES["guarda"]["type"]=="image/png")
   
{

         
# Escapa caracteres especiales
        $imagenEscapes
=mysqli_real_escape_string($link, file_get_contents($_FILES["guarda"]["tmp_name"]));
 

       $id
=mysqli_insert_id($link);
 

       
# Mostramos la imagen agregada

         echo
"Imagen agregada con el id .'$id'";

   
}else{

       echo
"Error El formato de archivo tiene que ser JPG, GIF, BMP o PNG";
     

   
}

}

$_GRABAR_SQL
= "INSERT INTO tabla_db2 (nombre,email,foto) VALUES ('$nombre','$email','".$imagenEscapes."')";  
mysqli_query
($link,$_GRABAR_SQL);

// Cerramos la conexion a la base de datos  
  mysqli_close
($link);

?>





imagen_mostrar.php
<?php


# debe recibir el id de la imagen a mostrar



 

# Conectamos con MySQL

$link
=mysqli_connect("localhost","root","","prueba");

if (mysqli_connect_errno()) {

   
die("Error al conectar: ".mysqli_connect_error());

}

 

# Buscamos la imagen a mostrar

$result
=mysqli_query($link,"SELECT * FROM `tabla_db2` WHERE id=".$_GET["id"]);

$row
=mysqli_fetch_array($result);

 

# Mostramos la imagen

header
("Content-type:".$row["tipo"]);

echo $row
["imagen"];

?>


Tordek

unread,
Nov 3, 2015, 10:44:12 PM11/3/15
to php...@googlegroups.com
Antes de entrar a mirar tu código, te recomiendo que NO guardes imágenes en la DB. Guardá URLs y guardá el archivo en disco. De esa manera no necesitás acceder a la DB por una imagen, y al final podés meterla en un CDN sin tener que reestructurar todo. Es _mucho_ mejor que guardar imágenes en la DB.


> pero al querer verla no me aparece.

¿Qué querés decir con "no me aparece"? ¿En el img no se ve? ¿qué pasa si entrás directamente a `imagen_mostrar.php?id=5`? ¿No retorna nada, o da un error? Decís que los datos se graban correctamente. ¿Cómo sabés? Es decir, ¿como sabés, si no ves la imagen, que se grabó correctamente?

> echo "<img src='imagen_mostrar.php?id=".$row["id"]."' nombre='".$row["nombre"]."' email='".$row["email"]."'>";

'nombre' y 'email' no son campos de html. No debería romperte nada en general, pero si querés agregar datos custom usá el prefijo data: "data-email=...".

# Escapa caracteres especiales

>  $imagenEscapes
=mysqli_real_escape_string($link, file_get_contents($_FILES["guarda"]["tmp_name"]));

Estás escapando la imagen, pero no el email ni el nombre. Nunca manejes esto a mano, porque podés olvidarte de hacerlo en algún campo. Mejor, usá prepared statements (y, preferiblemente, usá PDO antes que usar mysqli directamente (y, bueno, yo te diría que uses el "object oriented style" antes que el procedural, pero eso ya es de estilo)):

$statement = mysqli_prepare($link, "INSERT INTO tabla_db2 (nombre,email,foto) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($statement, "ssb", $nombre, $email, $imagen);

Al usar eso, todo lo que tenga que ver con escapes lo maneja el driver.

Además,

>
       $id=mysqli_insert_id($link);


acá estás pidiendo el id del último insert, pero todavía no ejecutaste una query. Te está devolviendo el ID de la fila anterior, no la actual. Eso tenés que ejecutarlo después del INSERT.

?>

Es una buena práctica omitir el tag de cierre final, porque, por ejemplo, podría pasar que estés presentando tu imagen correctamente, pero tenés un espacio o un enter después del tag de cierre, y eso aparece al final de tu imagen, invalidando el contenido.

$_GRABAR_SQL = "INSERT INTO tabla_db2 (nombre,email,foto) VALUES ('$nombre','$email','".$imagenEscapes."')";  
>  mysqli_query
($link,$_GRABAR_SQL);


Ojo con tu lógica: tenés un IF que revisa si el archivo existe, y si la imagen es válida... pero al fin y al cabo, grabás, haya o no imagen. Si eso es lo que querés, ignorá hasta el <===

Yo lo que te recomendaría es que lo escribas así:

<?php

// primero todas las validaciones
if (!isset($_POST['nombre'])) die "No pusiste nombre";
if (!isset($_POST['email'])) die "No pusiste mail";
// Acá pondrías otras validaciones como asegurarte que el nombre sea largo, o que el mail sea un mail.
if (!is_uploaded_file($_FILES["guarda"]["tmp_name"]))) die "No subiste imagen";

$TIPOS_VALIDOS = ['image/jpeg', 'image/jpg', 'image/gif', 'image/bmp', 'image/png'];

if (array_search($_FILES["guarda"]["type"], $TIPOS_VALIDOS) === false) die "La imagen no es de un tipo válidos";

// después todo lo que tenga que ver con usar esos datos

$statement = mysql_...

<===

No veo nada que me llame la atención (aunque no sé cómo interactúa mysqli_real_escape_string con un blob); fijate qué pasa al acceder a imagen_mostrar.php?id=5 directamente, si tira algún error (y asegurate de activar los errores en tu php.ini!)






--
Has recibido este mensaje porque estás suscrito al grupo "Grupo PHP Argentina" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a php-arg+u...@googlegroups.com.
Para publicar en este grupo, envía un correo electrónico a php...@googlegroups.com.
Visita este grupo en http://groups.google.com/group/php-arg.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Camello Ar

unread,
Nov 3, 2015, 11:01:33 PM11/3/15
to php...@googlegroups.com

Yo veo raro el tema de escapar una imagen. No deja de ser un binario y como tal tener carácteres que puedan ser erróneamente escapados.

Por otro lado si miras el código fuente (desde el navegador) de imagen_mostrar fíjate si te sale binario errores, espacios o líneas en blanco.

En lo personal,  y desconozco el destino del sistema (público o privado)  le agregaría un verificador al id de imagen, ya sea en dos campos id=123&verificar=A2d3 o concatenados (separar en el Php) id=123A2d3 o directamente asignar un valor arbitrario como id
Esto para evitar que mediante reemplazo del id se pueda acceder a cualquier imagen

Andrés Oporto

unread,
Nov 4, 2015, 3:47:16 AM11/4/15
to Grupo PHP Argentina
Cuando me refiero a que no se muestra la imagen, es porque me aparece en vez de la imagen un icono de una hoja rota, y cuando la inspecciono me dice que no se encuentra la url. puedo ver que me se me grabaron datos porque los veo en el administrador de base de datos. al intentar acceder a imagen_mostrar.php?id=5(po ejemplo) me ofrece guardar el archivo ohp que estpy usando en ese momento.

Adrian Ramiro

unread,
Nov 4, 2015, 6:40:56 AM11/4/15
to Grupo PHP Argentina

Por otro lado, el atributo src de un tag img debe ser una URL, no el archivo en sí, sino la ruta al mismo. Si por alguna razón quisieras o sirviera a tu aplicación volcar el archivo de esa manera, busca "data uri" para saber como implementarlo

Gabriel Divenuto

unread,
Nov 4, 2015, 6:49:37 AM11/4/15
to php...@googlegroups.com
en vez de $row['imagen'] no será $row['foto'] ? que es el nombre del campo para ola foto en la tabla de la DB.
Gabriel E. Divenuto
Web: www.sistemasgd.com

Gabriel Divenuto

unread,
Nov 4, 2015, 6:53:19 AM11/4/15
to php...@googlegroups.com
en el script mostrar_imagen.php, en las últimas líneas:

# Mostramos la imagen

header
("Content-type:".$row["tipo"]);


echo $row
["imagen"];            //AQUÍ NO SERÍA $row["foto"]?

Tordek

unread,
Nov 4, 2015, 9:21:17 AM11/4/15
to php...@googlegroups.com

Pero... tiene una url (bueno, tiene un nombre de archivo, pero se resuelve a una URL).

Tordek

unread,
Nov 4, 2015, 9:22:43 AM11/4/15
to php...@googlegroups.com

Y si guardás el archivo y lo abris con un visor de imágenes o un editor de texto, ¿qué tiene adentro?

On 4 Nov 2015 05:47, "Andrés Oporto" <ando...@gmail.com> wrote:
Cuando me refiero a que no se muestra la imagen, es porque me aparece en vez de la imagen un icono de una hoja rota, y cuando la inspecciono me dice que no se encuentra la url. puedo ver que me se me grabaron datos porque los veo en el administrador de base de datos. al intentar acceder a imagen_mostrar.php?id=5(po ejemplo) me ofrece guardar el archivo ohp que estpy usando en ese momento.

--

Andrés Oporto

unread,
Nov 4, 2015, 5:43:32 PM11/4/15
to Grupo PHP Argentina
se guardan como un archivo .bin, pero al cambiar la extensión a jpg se puede ver la foto

Camello Ar

unread,
Nov 4, 2015, 5:48:28 PM11/4/15
to php...@googlegroups.com

Pareciera que el problema es el tipo mime en content type en el header

El 04/11/2015 19:43, "Andrés Oporto" <ando...@gmail.com> escribió:
se guardan como un archivo .bin, pero al cambiar la extensión a jpg se puede ver la foto

--

Camello Ar

unread,
Nov 4, 2015, 5:53:10 PM11/4/15
to php...@googlegroups.com

Añado, viendo en detalle el mime lo sacas de $row[tipo] pero en la db no guardas el mime (tipo campo inexistente) , con lo cual no declara bien el formato al mostrar la imagen

Reply all
Reply to author
Forward
0 new messages